Home > Software engineering >  VBA calculate with numbers in range 10^40
VBA calculate with numbers in range 10^40

Time:01-06

I asked a similar question yesterday, but for smaller numbers. So today again :-)

I am trying to calculate: A random number in the range 10^40 mod a random number in the range of 100. I saved the first random number as a Variant because the number is too big to be saved as an Integer.

The result of the solution should be something between 1 and 100, so it could be saved as an Integer.

For example calculation: 3545123008254150481059068660418190917230 mod 97 = 37. How to calc this by using VBA.

My idea is to break down the numbers into smaller numbers (prim factorization) and calculate the modulo on smaller numbers, so we don't need to calculate in the range of 10^40.

Here the solution with smaller numbers:

Sub test_this()
    Debug.Print find_modulus("300400000717120000131495", 97)
End Sub

Function find_modulus(large_number As String, divisor As Long)
    Dim quotient As Variant, integer_quotient As Variant
    quotient = CDec(large_number)
    integer_quotient = Int(quotient / divisor) * divisor
    find_modulus = quotient - integer_quotient
End Function

The Output in this example is 1 and it is correct.

But with this calculation I get errors...
For example calculation: 3545123008254150481059068660418190917230 mod 97 = 37. How to calc this by using VBA.

CodePudding user response:

You can do the division in chunks, treating large numbers as a string and chopping them up into smaller pieces which can be processed in sequence.

To start with your example: 3545123008254150481059068660418190917230 Mod 97. We can take the first 9 digits "354512300". The Mod of this is "95". We prepend that onto the string and then take 9 digits to form the next sequence, "958254150". Repeat that for the entire string and eventually your last section is "55230", whose modulus is 37!

Function find_modulus(ByVal number As String, ByVal divisor As Long) As Long
    While Len(number) > 9
        number = (CLng(Left(number, 9)) Mod divisor) & CStr(Mid(number, 10))
    Wend
    find_modulus = CLng(number) Mod divisor
End Function

CodePudding user response:

Get Remainder From Large Integer

Sub GetLargeRemainderTEST()
    
    Const LargeInteger As String = "3545123008254150481059068660418190917230"
    Const Divisor As Long = 97

    Debug.Print GetLargeRemainder(LargeInteger, Divisor) ' 37

End Sub

Function GetLargeRemainder( _
    ByVal LargeInteger As String, _
    ByVal Divisor As Long) _
As Long
    
    Dim Dividend As String
    Dim Remainder As Long
    
    Do While Len(LargeInteger) > 0
        Dividend = IIf(Remainder = 0, "", CStr(Remainder)) _
            & Mid(LargeInteger, 1, 1)
        Remainder = CLng(Dividend) Mod Divisor
        'Debug.Print Dividend, Remainder, LargeInteger
        LargeInteger = Mid(LargeInteger, 2, Len(LargeInteger) - 1)
    Loop

    GetLargeRemainder = Remainder

End Function

Debug.Print Result

3              3            3545123008254150481059068660418190917230
35             35           545123008254150481059068660418190917230
354            63           45123008254150481059068660418190917230
635            53           5123008254150481059068660418190917230
531            46           123008254150481059068660418190917230
462            74           23008254150481059068660418190917230
743            64           3008254150481059068660418190917230
640            58           008254150481059068660418190917230
580            95           08254150481059068660418190917230
958            85           8254150481059068660418190917230
852            76           254150481059068660418190917230
765            86           54150481059068660418190917230
864            88           4150481059068660418190917230
881            8            150481059068660418190917230
85             85           50481059068660418190917230
850            74           0481059068660418190917230
744            65           481059068660418190917230
658            76           81059068660418190917230
761            82           1059068660418190917230
820            44           059068660418190917230
445            57           59068660418190917230
579            94           9068660418190917230
940            67           068660418190917230
676            94           68660418190917230
948            75           8660418190917230
756            77           660418190917230
776            0            60418190917230
0              0            0418190917230
4              4            418190917230
41             41           18190917230
418            30           8190917230
301            10           190917230
109            12           90917230
120            23           0917230
239            45           917230
451            63           17230
637            55           7230
552            67           230
673            91           30
910            37           0
 37
  • Related