3

I have a A1 with 2 and a cell A2 with 288. I want to calculate MOD(2^288;2017) but this gives the NUM error.

I also tried using this formula: =number-(INT(number/divisor)*divisor) but this gives 0 as a result when the numbers are too big.

EDIT: not completely duplicate (see my answer for the function in excel), I used this algorithm: How to calculate modulus of large numbers?

Community
  • 1
  • 1
Agnaroc
  • 167
  • 2
  • 10
  • You may want to check out Chip Pearson's article on this: `http://www.cpearson.com/excel/ModFunction.aspx` I tested it out and it still can't handle numbers as big as what you're looking to do, but it might give you some ideas on where to go. – Brian Powell Dec 23 '15 at 17:29
  • Yes, I already checked the article before asking my question on stackoverflow. Unfortunately it still doesn't work with the custom function. – Agnaroc Dec 23 '15 at 17:52
  • Possible duplicate of [How to calculate modulus of large numbers?](http://stackoverflow.com/questions/2177781/how-to-calculate-modulus-of-large-numbers) – Ron Rosenfeld Dec 23 '15 at 18:01
  • I can only use excel (on the exam). I can't add any add-ins :/ – Agnaroc Dec 23 '15 at 18:24
  • Well, then, your question has probably already been answered by the duplicate. – Ron Rosenfeld Dec 23 '15 at 18:33

3 Answers3

1

To solve this problem add this function in excel: alt+f11 -> module -> add and use BigMod(2;288;2017) if you want to calculate 2^288 mod 2017

Public Function BigMod(ByVal grondgetal As Double, ByVal exponent As Integer, ByVal modgetal As Double) As Double

  Dim hulp As Integer
  hulp = 1

  Dim i As Integer

    For i = 1 To exponent
        hulp = hulp * grondgetal
        hulp = hulp - Int(hulp / modgetal) * modgetal
    Next i
  BigMod = hulp

End Function
Hambone
  • 15,600
  • 8
  • 46
  • 69
Agnaroc
  • 167
  • 2
  • 10
0

I needed it to work with a very large number. The example above works if i take 3 followed by 7 sections of 0's, but breaks if I keep going.

So I worked out how I would do it on paper and wrote a function that will handle it that way. Since it only works with one section at a time (plus the remainder from the prior section) it is never working with a value larger than 1 million.

Public Function AnyMod(ByVal numerator As String, ByVal denominator As Double) As Double
    ' inch worm through the numerator working one section at a time to get the remainder given any size string
    Dim numericalDivider As String
    Dim decimalDivider As String
    Dim sectionLength As Integer

    ' in the US
    numericalDivider = ","
    decimalDivider = "."
    sectionLength = 3

    ' in Europe
    'numericalDivider = "."
    'decimalDivider = ","
    'sectionLength = 3

    ' input cleanup - replace numerical section divider
    numerator = Replace(numerator, numericalDivider, "")

    ' input cleanup - chop any decimal off of it
    If (InStr(1, numerator, decimalDivider)) Then
        numerator = Left(numerator, InStr(1, numerator, decimalDivider) - 1)
    End If

    Dim pos As Integer              ' the next position in numerator to be read
    Dim remainder As Double         ' the remainder of the last division
    Dim subs As String              ' the current section being read
    Dim length As Integer           ' the total length of numerator
    Dim current As Double           ' the current value being worked on
    Dim firstSegment As Integer     ' the length of the first piece

    'set up starting values
    length = Len(numerator)

    firstSegment = length Mod sectionLength
    If firstSegment = 0 Then firstSegment = sectionLength

    remainder = 0
    pos = 1

    'handle the first section
    subs = Mid(numerator, pos, firstSegment)
    pos = pos + firstSegment

    ' handle all of the middle sections
    While pos < length
        ' work with the current section
        ' (10 ^ sectionLength) is 1000 when sectionLength is 3.  basically shifting the decimal
        current = remainder * (10 ^ sectionLength) + subs
        remainder = current Mod denominator

        ' determine the next section
        subs = Mid(numerator, pos, sectionLength)
        pos = pos + sectionLength
    Wend

    ' handle the last section
    current = remainder * (10 ^ sectionLength) + subs
    remainder = current Mod denominator

    ' return the response
    AnyMod = remainder

End Function

Call it like =AnyMod(Text(A1, "0"), 2017)

In your case you'd need to get the value of 2^288, but this works if you have a large value in a cell and want to get a remainder.

isopropanol
  • 445
  • 4
  • 10
-1

Excel might be forcing an integer context on your values. Even an Int64 is not sufficient to handle numbers that large.

You might need a custom VBA function to handle that. If you cast the inputs and outputs as doubles and then brute-forcing the modulus functionality, it should be capable of doing the math.

My problem would be validating the output... I have no idea if this is the right value or not.

Public Function BigMod(ByVal numerator As Double, ByVal denominator As Double) As Double

  Dim intval As Double
  intval = Int(numerator / denominator)

  BigMod = numerator - intval * denominator

End Function

This works on values larger than Mod will handle, but does eventually break.

For instance, 3 followed by 5 sets of 0's will break Mod. 3 followed by 6 sets of 0's will break BigMod.

isopropanol
  • 445
  • 4
  • 10
Hambone
  • 15,600
  • 8
  • 46
  • 69
  • When I use this method I get 3.72586E+70 when I try BigMod(2^288;2017) ... Other (smaller) calculations are correct though. – Agnaroc Dec 23 '15 at 17:48
  • @Agnaroc -- for testing purposes, what is the correct answer? When I asked Perl, it told me 4.97323236409787e+86 – Hambone Dec 23 '15 at 20:09
  • Sorry for my late answer, this is the solution (2, 3, 4 en 5 are exponentiated) [Picture](http://puu.sh/m71ra/da0d7e516c.png) – Agnaroc Dec 24 '15 at 10:29
  • code doesnt work try using `DblMod = numerator - floor * denominator` instead – DeveloperChris Jul 03 '18 at 03:08