I was running code in an attempt to figure out the behavior of Java when losing precision due to casting between the integral decimal numeric types, and I found an unexpected result:
long l2 = 999999999999999999L; //outside of range -2147483648..2147483647 for int
int i3=(int)l2;
System.out.println(l2); //999999999999999999, as expected.
System.out.println(i3); //I expected 2147483647, but got -1486618625
Can someone please explain how I'm getting a large negative int out of a large positive long? I would have expected the system to at least make a best effort casting attempt, returning the maximum positive integer (the closest valid int to the long which is too large to be stored in integer.) Instead, I'm getting a negative number which does not make sense to me.
The narrowing primitive conversion of a long
to an int
discards all but the lower order 32 bits of the original number, so you don't get Integer.MAX_VALUE
.
The JLS, Section 5.1.3, states:
A narrowing conversion of a signed integer to an integral type T simply discards all but the n lowest order bits, where n is the number of bits used to represent type T. In addition to a possible loss of information about the magnitude of the numeric value, this may cause the sign of the resulting value to differ from the sign of the input value.
This is in contrast to a primitive narrowing conversion from a floating-point type to an int
, which may result in Integer.MAX_VALUE
if the original value was too big.
double l2 = 999999999999999999.0;
System.out.println((int) l2);
This prints:
2147483647