How to avoid overflow in modular multiplication?

Consider below simple method to multiply two numbers.

filter_none

edit
close

play_arrow

link
brightness_4
code

// A Simple solution that causes overflow when 
// value of (a % mod) * (b % mod) becomes more than
// maximum value of long long int 
#define ll long long
  
ll multiply(ll a, ll b, ll mod)
{
   return ((a % mod) * (b % mod)) % mod;
}

chevron_right


The above function works fine when multiplication doesn’t result in overflow. But if input numbers are such that the result of multiplication is more than maximum limit.

For example, the above method fails when mod = 1011, a = 9223372036854775807 (largest long long int) and b = 9223372036854775807 (largest long long int). Note that there can be smaller values for which it may fail. There can be many more examples of smaller values. In fact any set of values for which multiplication can cause a value greater than maximum limit.



How to avoid overflow?
We can multiply recursively to overcome the difficulty of overflow. To multiply a*b, first calculate a*b/2 then add it twice. For calculating a*b/2 calculate a*b/4 and so on (similar to log n exponentiation algorithm).

// To compute (a * b) % mod
multiply(a,  b, mod)
1)  ll res = 0; // Initialize result
2)  a = a % mod.
3)  While (b > 0)
        a) If b is odd, then add 'a' to result.
               res = (res + a) % mod
        b) Multiply 'a' with 2
           a = (a * 2) % mod
        c) Divide 'b' by 2
           b = b/2  
4)  Return res 

Below is the implementation.

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program for modular multiplication without
// any overflow
#include<iostream>
using namespace std;
  
typedef long long int ll;
  
// To compute (a * b) % mod
ll mulmod(ll a, ll b, ll mod)
{
    ll res = 0; // Initialize result
    a = a % mod;
    while (b > 0)
    {
        // If b is odd, add 'a' to result
        if (b % 2 == 1)
            res = (res + a) % mod;
  
        // Multiply 'a' with 2
        a = (a * 2) % mod;
  
        // Divide b by 2
        b /= 2;
    }
  
    // Return result
    return res % mod;
}
  
// Driver program
int main()
{
   ll a = 9223372036854775807, b = 9223372036854775807;
   cout << mulmod(a, b, 100000000000);
   return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program for modular multiplication  
// without any overflow 
  
class GFG 
{
  
    // To compute (a * b) % mod 
    static long mulmod(long a, long b, 
                            long mod) 
    {
        long res = 0; // Initialize result 
        a = a % mod;
        while (b > 0)
        {
            // If b is odd, add 'a' to result 
            if (b % 2 == 1
            {
                res = (res + a) % mod;
            }
  
            // Multiply 'a' with 2 
            a = (a * 2) % mod;
  
            // Divide b by 2 
            b /= 2;
        }
  
        // Return result 
        return res % mod;
    }
  
    // Driver code 
    public static void main(String[] args)
    {
  
        long a = 9223372036854775807L, b = 9223372036854775807L;
        System.out.println(mulmod(a, b, 100000000000L));
    }
  
// This code is contributed by Rajput-JI

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program for modular multiplication 
# without any overflow
  
# To compute (a * b) % mod
def mulmod(a, b, mod):
  
    res = 0; # Initialize result
    a = a % mod;
    while (b > 0):
      
        # If b is odd, add 'a' to result
        if (b % 2 == 1):
            res = (res + a) % mod;
  
        # Multiply 'a' with 2
        a = (a * 2) % mod;
  
        # Divide b by 2
        b //= 2;
  
    # Return result
    return res % mod;
  
# Driver Code
a = 9223372036854775807;
b = 9223372036854775807;
print(mulmod(a, b, 100000000000));
  
# This code is contributed by mits

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program for modular multiplication 
// without any overflow 
using System;
  
class GFG 
  
// To compute (a * b) % mod 
static long mulmod(long a, long b, long mod) 
    long res = 0; // Initialize result 
    a = a % mod; 
    while (b > 0) 
    
        // If b is odd, add 'a' to result 
        if (b % 2 == 1) 
        
            res = (res + a) % mod; 
        
  
        // Multiply 'a' with 2 
        a = (a * 2) % mod; 
  
        // Divide b by 2 
        b /= 2; 
    
  
    // Return result 
    return res % mod; 
  
// Driver code 
public static void Main(String[] args) 
    long a = 9223372036854775807L, 
         b = 9223372036854775807L; 
    Console.WriteLine(mulmod(a, b, 100000000000L)); 
  
// This code is contributed by 29AjayKumar

chevron_right


Output:

84232501249

Thanks to Utkarsh Trivedi for suggesting above solution.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above



My Personal Notes arrow_drop_up