Skip to content
Related Articles
Open in App
Not now

Related Articles

Multiply large integers under large modulo

Improve Article
Save Article
  • Difficulty Level : Medium
  • Last Updated : 20 Dec, 2022
Improve Article
Save Article

Given an integer a, b, m. Find (a * b ) mod m, where a, b may be large and their direct multiplication may cause overflow. However, they are smaller than half of the maximum allowed long long int value.

Examples: 

Input: a = 426, b = 964, m = 235
Output: 119
Explanation: (426 * 964) % 235  = 410664 % 235 = 119

Input: a = 10123465234878998, 
          b = 65746311545646431
         m = 10005412336548794 
Output: 4652135769797794

Naive Approach: A naive approach is to use arbitrary precision data types such as int in python or Biginteger class in Java. But that approach will not be fruitful because the internal conversion of string to int and then perform operation will lead to slow down the calculations of addition and multiplications in the binary number system.

Efficient Approach: Since a and b may be very large numbers, if we try to multiply directly, they will definitely overflow. Therefore we use the basic approach of multiplication i.e., a * b = a + a + … + a (b times). Now easily compute the value of addition (under modulo m) without any overflow in the calculation. But if we try to add the value of a repeatedly up to b times then it will definitely timeout for the large value of b, since the time complexity of this approach would become O(b).

So, divide the above-repeated steps for a in simpler way i.e., 

If b is even then 
a * b = 2 * a * (b / 2), 

otherwise 
a * b = a + a * (b – 1)

Below is the approach describing the above explanation : 

C++




// C++ program of finding modulo multiplication
#include <bits/stdc++.h>
 
using namespace std;
 
// Returns (a * b) % mod
long long moduloMultiplication(long long a, long long b,
                               long long mod)
{
    long long res = 0; // Initialize result
 
    // Update a if it is more than
    // or equal to mod
    a %= mod;
 
    while (b) {
        // If b is odd, add a with result
        if (b & 1)
            res = (res + a) % mod;
 
        // Here we assume that doing 2*a
        // doesn't cause overflow
        a = (2 * a) % mod;
 
        b >>= 1; // b = b / 2
    }
 
    return res;
}
 
// Driver program
int main()
{
    long long a = 426;
    long long b = 964;
    long long m = 235;
    cout << moduloMultiplication(a, b, m);
    return 0;
}
 
// This code is contributed
// by Akanksha Rai

C




// C program of finding modulo multiplication
#include<stdio.h>
 
// Returns (a * b) % mod
long long moduloMultiplication(long long a,
                               long long b,
                               long long mod)
{
    long long res = 0;  // Initialize result
 
    // Update a if it is more than
    // or equal to mod
    a %= mod;
 
    while (b)
    {
        // If b is odd, add a with result
        if (b & 1)
            res = (res + a) % mod;
 
        // Here we assume that doing 2*a
        // doesn't cause overflow
        a = (2 * a) % mod;
 
        b >>= 1;  // b = b / 2
    }
 
    return res;
}
 
// Driver program
int main()
{
    long long a = 10123465234878998;
    long long b = 65746311545646431;
    long long m = 10005412336548794;
    printf("%lld", moduloMultiplication(a, b, m));
    return 0;
}

Java




// Java program of finding modulo multiplication
import java.util.*;
import java.io.*;
class GFG
{
 
    // Returns (a * b) % mod
    static long moduloMultiplication(long a,
                            long b, long mod)
    {
         
        // Initialize result
        long res = 0
 
        // Update a if it is more than
        // or equal to mod
        a %= mod;
 
        while (b > 0)
        {
             
            // If b is odd, add a with result
            if ((b & 1) > 0)
            {
                res = (res + a) % mod;
            }
 
            // Here we assume that doing 2*a
            // doesn't cause overflow
            a = (2 * a) % mod;
 
            b >>= 1; // b = b / 2
        }
        return res;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        long a = 10123465234878998L;
        long b = 65746311545646431L;
        long m = 10005412336548794L;
        System.out.print(moduloMultiplication(a, b, m));
    }
}
 
// This code is contributed by Rajput-JI

Python3




# Python 3 program of finding
# modulo multiplication
 
# Returns (a * b) % mod
def moduloMultiplication(a, b, mod):
 
    res = 0; # Initialize result
 
    # Update a if it is more than
    # or equal to mod
    a = a % mod;
 
    while (b):
     
        # If b is odd, add a with result
        if (b & 1):
            res = (res + a) % mod;
             
        # Here we assume that doing 2*a
        # doesn't cause overflow
        a = (2 * a) % mod;
 
        b >>= 1; # b = b / 2
     
    return res;
 
# Driver Code
a = 10123465234878998;
b = 65746311545646431;
m = 10005412336548794;
print(moduloMultiplication(a, b, m));
     
# This code is contributed
# by Shivi_Aggarwal

C#




// C# program of finding modulo multiplication
using System;
 
class GFG
{
     
// Returns (a * b) % mod
static long moduloMultiplication(long a,
                            long b,
                            long mod)
{
    long res = 0; // Initialize result
 
    // Update a if it is more than
    // or equal to mod
    a %= mod;
 
    while (b > 0)
    {
        // If b is odd, add a with result
        if ((b & 1) > 0)
            res = (res + a) % mod;
 
        // Here we assume that doing 2*a
        // doesn't cause overflow
        a = (2 * a) % mod;
 
        b >>= 1; // b = b / 2
    }
 
    return res;
}
 
// Driver code
static void Main()
{
    long a = 10123465234878998;
    long b = 65746311545646431;
    long m = 10005412336548794;
    Console.WriteLine(moduloMultiplication(a, b, m));
}
}
 
// This code is contributed
// by chandan_jnu

PHP




<?php
//PHP program of finding
// modulo multiplication
 
// Returns (a * b) % mod
function moduloMultiplication($a, $b, $mod)
{
    $res = 0; // Initialize result
 
    // Update a if it is more than
    // or equal to mod
    $a %= $mod;
 
    while ($b)
    {
         
        // If b is odd,
        // add a with result
        if ($b & 1)
            $res = ($res + $a) % $mod;
 
        // Here we assume that doing 2*a
        // doesn't cause overflow
        $a = (2 * $a) % $mod;
 
        $b >>= 1; // b = b / 2
    }
 
    return $res;
}
 
    // Driver Code
    $a = 10123465234878998;
    $b = 65746311545646431;
    $m = 10005412336548794;
    echo moduloMultiplication($a, $b, $m);
 
// This oce is contributed by ajit
?>

Javascript




<script>
 
// JavaScript program for the above approach
 
// Returns (a * b) % mod
function moduloMultiplication(a, b, mod)
{
     
    // Initialize result
    let res = 0; 
 
    // Update a if it is more than
    // or equal to mod
    a = (a % mod);
 
    while (b > 0)
    {
         
        // If b is odd, add a with result
        if ((b & 1) > 0)
        {
            res = (res + a) % mod;
        }
 
        // Here we assume that doing 2*a
        // doesn't cause overflow
        a = (2 * a) % mod;
 
        b = (b >> 1); // b = b / 2
    }
    return res;
}
 
// Driver Code
let a = 426;
let b = 964;
let m = 235;
 
document.write(moduloMultiplication(a, b, m));
 
// This code is contributed by code_hunt
 
</script>

Output

119

Time complexity: O(log b), A number n has log(n) bits therefore the loop will run log(b) times.
Auxiliary space: O(1)

Note: Above approach will only work if 2 * m can be represented in standard data type otherwise it will lead to overflow. 

This article is contributed by Shubham Bansal. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
 


My Personal Notes arrow_drop_up
Related Articles

Start Your Coding Journey Now!