Multiply large integers under large modulo
Last Updated :
13 Sep, 2023
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++
#include <bits/stdc++.h>
using namespace std;
long long moduloMultiplication( long long a, long long b,
long long mod)
{
long long res = 0;
a %= mod;
while (b) {
if (b & 1)
res = (res + a) % mod;
a = (2 * a) % mod;
b >>= 1;
}
return res;
}
int main()
{
long long a = 426;
long long b = 964;
long long m = 235;
cout << moduloMultiplication(a, b, m);
return 0;
}
|
C
#include<stdio.h>
long long moduloMultiplication( long long a,
long long b,
long long mod)
{
long long res = 0;
a %= mod;
while (b)
{
if (b & 1)
res = (res + a) % mod;
a = (2 * a) % mod;
b >>= 1;
}
return res;
}
int main()
{
long long a = 10123465234878998;
long long b = 65746311545646431;
long long m = 10005412336548794;
printf ( "%lld" , moduloMultiplication(a, b, m));
return 0;
}
|
Java
import java.util.*;
import java.io.*;
class GFG
{
static long moduloMultiplication( long a,
long b, long mod)
{
long res = 0 ;
a %= mod;
while (b > 0 )
{
if ((b & 1 ) > 0 )
{
res = (res + a) % mod;
}
a = ( 2 * a) % mod;
b >>= 1 ;
}
return res;
}
public static void main(String[] args)
{
long a = 10123465234878998L;
long b = 65746311545646431L;
long m = 10005412336548794L;
System.out.print(moduloMultiplication(a, b, m));
}
}
|
Python3
def moduloMultiplication(a, b, mod):
res = 0 ;
a = a % mod;
while (b):
if (b & 1 ):
res = (res + a) % mod;
a = ( 2 * a) % mod;
b >> = 1 ;
return res;
a = 10123465234878998 ;
b = 65746311545646431 ;
m = 10005412336548794 ;
print (moduloMultiplication(a, b, m));
|
C#
using System;
class GFG
{
static long moduloMultiplication( long a,
long b,
long mod)
{
long res = 0;
a %= mod;
while (b > 0)
{
if ((b & 1) > 0)
res = (res + a) % mod;
a = (2 * a) % mod;
b >>= 1;
}
return res;
}
static void Main()
{
long a = 10123465234878998;
long b = 65746311545646431;
long m = 10005412336548794;
Console.WriteLine(moduloMultiplication(a, b, m));
}
}
|
PHP
<?php
function moduloMultiplication( $a , $b , $mod )
{
$res = 0;
$a %= $mod ;
while ( $b )
{
if ( $b & 1)
$res = ( $res + $a ) % $mod ;
$a = (2 * $a ) % $mod ;
$b >>= 1;
}
return $res ;
}
$a = 10123465234878998;
$b = 65746311545646431;
$m = 10005412336548794;
echo moduloMultiplication( $a , $b , $m );
?>
|
Javascript
<script>
function moduloMultiplication(a, b, mod)
{
let res = 0;
a = (a % mod);
while (b > 0)
{
if ((b & 1) > 0)
{
res = (res + a) % mod;
}
a = (2 * a) % mod;
b = (b >> 1);
}
return res;
}
let a = 426;
let b = 964;
let m = 235;
document.write(moduloMultiplication(a, b, m));
</script>
|
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.
Share your thoughts in the comments
Please Login to comment...