0

I went through the below mentioned tutorial and I tried calculating the modulo inverse of the number in C as well as in Java but in both cases , I am getting the output as 0 ,please guide me in my correcting my code .

https://www.hackerearth.com/practice/math/number-theory/multiplicative-inverse/tutorial/

import java.lang.Math;
import java.util.*;
import java.math.BigInteger;
import java.math.BigDecimal;
class TestClass {
    public static void main(String args[] ) throws Exception {
       Scanner sc=new Scanner(System.in);
       int a=sc.nextInt();
       BigInteger bi=BigInteger.valueOf(a);
       BigInteger k = new BigDecimal(Math.pow(10,9)).toBigInteger();
       BigInteger b=k.add(BigInteger.valueOf(7));
       BigInteger c=b.subtract(BigInteger.valueOf(2));
       BigInteger m=bi.modPow(c,BigInteger.valueOf(1));
       BigInteger d=m.mod(b);
       System.out.println(d);

    }
}

In C ,

#include <stdio.h>
#include<inttypes.h>
#include<math.h>
int main()
{
    uintmax_t a;
    scanf(" %ju",&a);
    uintmax_t b=pow(10,9);
    uintmax_t m=b+7;
    uintmax_t c=((uintmax_t)pow(a,m-2))%(m);
    printf("%ju",c);
    return 0;
}

I am unable to get the reason behind the overflow here ,please clarify this .

user123
  • 271
  • 1
  • 10
  • There is no `BigInteger` or `BigDecimal` in C. If you want arbitrary sized integers, you need to write the code yourself or use an add-on library. Needless to say, any "hackerrank" question that requires integers that go beyond 64-bit are better solved in languages that have support for these types, and `C` is not one of those languages. Also, [do not use pow() if your exponent is an integer](http://stackoverflow.com/questions/25678481/why-does-pown-2-return-24-when-n-5-with-my-compiler-and-os) – PaulMcKenzie Sep 25 '16 at 09:20
  • 1
    I'd wager the reason for the overflow is here: `((uintmax_t)pow(a,m-2))` any `a > 1` will be unimaginably large if raised to the power of `10^9`, and certainly larger than the largest number representable by an `uintmax_t`. – Andreas Grapentin Sep 25 '16 at 09:22
  • pow() function is double type, result maybe is OK in integer context, maybe not – Jacek Cz Sep 25 '16 at 09:37

1 Answers1

1

The reason your java code does not work is that

BigInteger m=bi.modPow(c,BigInteger.valueOf(1));

calculates bi^c mod 1, which is 0 for any bi and c.

What you want to calculate is bi^c mod b, which is coded as

BigInteger m = bi.modPow(c, b);

Since C does not have a powmod function you need to program it yourself.

The following function calculates x^e mod m:

uintmax_t powmod(uintmax_t x, uintmax_t e, uintmax_t m) {
    uintmax_t result = 1;
    while (e > 0) {
        if (e&1) {
            result = result * x % m;
        }
        x = x * x % m;
        e >>= 1;
    }
    return result;
}
Thomas Kläger
  • 17,754
  • 3
  • 23
  • 34
  • @user123 I've added a powmod function for C – Thomas Kläger Sep 25 '16 at 13:13
  • I am unable to understand the point if (e&1) { result = result * x % m; } It means that if exponent is odd then result=result*x%m , couldn't get this point . – user123 Sep 25 '16 at 13:24
  • I have written the function for calculating powmod ,plz check still I am not getting the desired output : http://codepad.org/w1L4z7L4 – user123 Sep 25 '16 at 13:27
  • You are using `unsigned long` which is too small for the intermediate results (`x*x` and function result times `x`), so you have to use `unsigned long long` or `uintmax_t`. And please beware that `(x%m )* function((x*x)%m, (n-1)/2)` might be greater than `m`. @user123 – Thomas Kläger Sep 25 '16 at 20:35