0
import java.util.*;  

class ModuloInverse {

    static long mod = 1000000007;

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        long num = in.nextLong();
        System.out.println(m_inverse(num, mod));
    }

    static long m_inverse(long a, long p) {
        return m_pow(a, p - 2);
    }

    static long m_pow(long n, long m) {
        long result = 0;

        if (m == 1) {
            return (n % mod);
        }

        if (m % 2 == 0) {
            result = m_pow(n, m / 2);

            return ((result * result) % mod);
        } else {
            result = m_pow(n, (m - 1) / 2);

            return (((n % mod) * (result * result)) % mod);
        }
    }
}

This is the java program I wrote to calculate multiplicative Modulo Inverse (modulo 10^9+7). But it gives negative numbers as output for numbers greater than 10. Can't figure out what's wrong.

Tiny
  • 27,221
  • 105
  • 339
  • 599
  • 1
    Just a note: a faster method to calculate the modular inverse is the extended euclidean algorithm. You may also want to have a look at the `BigInteger.modInverse()` method. – Henry Aug 04 '14 at 19:11
  • Henry, I'll look into that surely. – Saurabh Mehta Aug 05 '14 at 01:23

2 Answers2

1
But it gives negative numbers as output for numbers greater than 10

That is because youve already reached the positive overflow of long thus going back/starts at the negative overflow.

long has this value ranges from minimum value of -2^63 and a maximum value of 2^63-1 by the time you reach 2^63-1 it will then go back to -2^63 and starts from there.

Rod_Algonquin
  • 26,074
  • 6
  • 52
  • 63
1

I added a couple of debugging lines to your if statement at the bottom:

    if (m % 2 == 0) {
        result = m_pow(n, m / 2);
        System.out.println("m = " + m + ", result = " + result + ", returning " + ((result * result) % mod));
        return ((result * result) % mod);
    } else {
        result = m_pow(n, (m - 1) / 2);
        System.out.println("m = " + m + ", n % mod = " + (n % mod) + ", result = " + result + ", returning " + (((n % mod) * (result * result)) % mod));
        return (((n % mod) * (result * result)) % mod);
    }

When I ran this with the value 13, this was the last line printed out:

m = 1000000005, n % mod = 13, result = 846153852, returning -428497853

Now 846153852 × 846153852 × 13 > 263, so your code is overflowing the range of a Java long.

mod is 109 + 7, and if result is between 0 and mod, then result * result won't be much more than 1018, certainly less than 1.1 × 1018. The maximum positive value a long can hold is about 9.2 × 1018, so once n creeps above about 9, there is the chance that result * result * n will exceed this value. As far as I can see, this first happens with n = 13.

The product of two numbers modulo mod will never exceed the range of a Java long, but the product of three or more numbers might do.

One way to fix this is by replacing the line

return (((n % mod) * (result * result)) % mod);

with

return (((n % mod) * ((result * result) % mod) % mod);
Luke Woodward
  • 63,336
  • 16
  • 89
  • 104
  • Luke Woodward, Man you Rock. – Saurabh Mehta Aug 05 '14 at 01:18
  • @SaurabhMehta: which values of `n` were giving you negative results? I ran your code from 0 to `mod - 1` and told it to print out any negative results. It printed out nothing. Your change cannot possibly have made a difference: all you have done is stick an extra pair of parentheses around an already-parenthesised expression, i.e. replaced `(expr)` with `((expr))`. – Luke Woodward Aug 05 '14 at 19:52