Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid overflow in fast modular exponentiation

I am trying to solve a question on SPOJ which requires modular exponentiation. I am using the following C code

long long modpow(long long a,long long b,long long mod)
{
    long long product,pseq;
    product=1
    pseq=a%mod;
    while(b>0)
    {
        if(b&1)
            product=(product*pseq)%mod;
        pseq=(pseq*pseq)%mod;
        b>>=1
    }
    return product;
}

The problem is when I want to calculate (2^249999999997)%999999999989, it gives answer 0 because of overflow. How can I avoid overflow?

like image 463
jyotesh Avatar asked Oct 21 '22 04:10

jyotesh


1 Answers

Untestet, but you get the idea. This should work as long as 2*mod is less than the maximum representable long long value and a, b, and mod are positive.

long long modpow(long long a,long long b,long long mod)
{
    long long product,pseq;
    product=1;
    pseq=a%mod;
    while(b>0)
    {
        if(b&1)
            product=modmult(product,pseq,mod);
        pseq=modmult(pseq,pseq,mod);
        b>>=1;
    }
    return product;
}

long long modmult(long long a,long long b,long long mod)
{
    if (a == 0 || b < mod / a)
        return (a*b)%mod;
    long long sum;
    sum = 0;
    while(b>0)
    {
        if(b&1)
            sum = (sum + a) % mod;
        a = (2*a) % mod;
        b>>=1;
    }
    return sum;
}
like image 171
Henrik Avatar answered Oct 24 '22 02:10

Henrik