First things first, long b = a * a
overflows, since it should have the value 100.000.000.140.000.000.049
and it's greater than the max value of a signed long (2^63 - 1 = 9.223.372.036.854.775.807
).
Secondly, I think it should be said that there are some differences between the two operation that you've used. As stated in the comments of this answer, java has the reminder operator %
and does not provide a modulo operator or a function, like BigInteger
does. Those are two slightly different things.
Mathematically if you want the result of c, given as c = a (mod b), it will be a number such that 1 < c < b (e.g. 4 (mod 3) = 1
). Consequently, if b = a * a, then b (mod a) = a * a (mod a) = 0.
If you want to read more about it, I suggest you to take a look at modular arithmetic.
The java reminder operator %
, gives the reminder of the division (considering n % d
), which has n as the numerator and d as the denominator. When mixing positive and negative numbers, there could be some inconsistencies with n (mod d), since
mod and remainder are actually semantically different operations
In conclusion, if you want to use modulo, you should rely on the functions provided from BigInteger, otherwise use the reminder operator.
I also suggest this reading that explain the difference between modulus and reminder.