there is something puzzling me and I did not find much information on the VM specs. It’s a bit obscure and that’d be nice if someone could explain me.
These few lines of code…..
double myTest = Double.MAX_VALUE;
System.out.println("1. float: " + (float)myTest);
System.out.println("2. int: " + (int)myTest);
System.out.println("3. short: " + (short)myTest);
System.out.println("4. byte: " + (byte)myTest);
….. produce this output:
- float: Infinity
- int: 2147483647
- short: -1
- byte: -1
byte, short and int are 8, 16, 32 bit with two’s complement. float and double are 32 and 64 bit IEEE 754 (see here).
From my understanding, the max value of a double implies that all the bits of the mantisse (52 bits) are switched to 1. Therefore it’s not (very) surprising that a cast to short or to byte returns -1 i.e all bits are switched to 1. It seems that the cast keeps the ‘tail’ of the double so that it fits into 8 bit byte or 16 bit short.
What surprises me is the cast to int and, to a lesser extent, the cast to float.
How is it possible to get “2. int: 2147483647” which is 0x7FFFFFFF, the maximal value while short and byte 3. and 4. are -1 ?
The cast to float is also weird. If the 32 bits at the ‘tail’ of myTest were kept, then shouldn’t it generate a NaN ?
JLS spells out the rules in section 5.1.3 Narrowing Primitive Conversion. The rules depend on the target type.
float:intandlong:byte,charandshort:If the target type is
byte,charorshort, the conversion it two-step. First, thedoubleis converted tolongas explained above. Then, thelongis converted to the final type as follows: