0 : 1 1
1 : 1 1
2 : 2 2
3 : 6 6
4 : 24 24
5 : 120 120
6 : 720 720
7 : 5040 5040
8 : 40320 40320
9 : 362880 362880
10 : 3628800 3628800
11 : 39916800 39916800
12 : 479001600 479001600
13 : 1932053504 1932053504
14 : 1278945280 1278945280
15 : 2004310016 2004310016
16 : 2004189184 2004189184
17 : -288522240 -288522240
Im wondering : How does java deal with multiplication overflows ? I guess since its a primitive operation, there is no way to throw an exception....
But I have had NaN exceptions before, which I think are much cleaner.
Any idea regarding the JVM specifics on this ?
jay vas wrote:Im wondering : How does java deal with multiplication overflows ? I guess since its a primitive operation, there is no way to throw an exception....
Java could have thrown an exception here - they just chose not to. They throw an exception if you divide by zero in integer division, for example. I think it was a bad decision not to throw an exception in the case of overflow, but they were probably trying to mimic existing behavior of c programs that people were used to back then.
jay vas wrote:But I have had NaN exceptions before, which I think are much cleaner.
They probably weren't NaN exceptions, but NaN results. These are possible values in floating-point operations, but not integer operations.
jay vas wrote:Any idea regarding the JVM specifics on this ?
Basically integer multiplication in java behaves as if the multiplication was done correctly, except that only the lowest 32 bits of the answer are retained. (Or 64 bits if any longs are involved.) No error or warning is given. It's very poor engineering, in my opinion.
If your program theoretically uses infinite precision, you might want to consider using a BigInteger instead of regular ints or longs.
As Mike says, Java™ retains the rightmost 32 bits (or 64 for a long), so overflow is actually deterministic and predictable.
Rob Spoor wrote:They shouldn't have thrown exceptions automatically, they should have gone the C# way - let the programmer decide to allow or deny overflow.
100% agree, there are valid reasons to want to allow overflow, and sometimes you need it. As long as the default is to throw an exception. Or in some languages the default is to use an infinite-precision datatype - that can work well too.