Drop double and other numeric type

Something puzzles me, and I did not find much information about the specifications of VM. This is a bit unclear, and it would be nice if someone could explain to me.

These are a 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 conclusion:

  • float: infinity
  • int: 2147483647
  • short: -1
  • byte: -1

byte , short and int - 8, 16, 32 bits with two additions. float and double - 32 and 64 bits of IEEE 754 ( see here ).

From my understanding, the maximum value of a double implies that all the mantissa bits (52 bits) are switched to 1. Therefore, it is (very) not surprising that casting to short or byte returns -1 i.e. all bits are switched to 1. It seems that the cast holds the tail of the double so that it enters 8 byte bits or 16 short bits.

What surprises me is casting to int and, to a lesser extent, casting to float . How can I get "2. int: 2147483647", which is 0x7FFFFFFF, the maximum value while short and bytes 3. and 4. are -1?

Casting to float also weird. If the 32 bits in the tail of myTest were stored, then it should not generate NaN ?

+6
source share
1 answer

JLS outlines the rules in section 5.1.3 Narrowing down a primitive transform . The rules depend on the type of goal.

float :

The narrowing of the primitive conversion from double to float is governed by the rounding rules of IEEE 754 (ยง4.2.4). This conversion may lose accuracy, but also lose range, resulting in a floating-point zero from a non-zero double and floating-point infinity from a finite double. Double NaN is converted to float NaN, and double infinity is converted to infinite floating-point infinity.

int and long :

one of the following two cases must be performed:

  • ...
  • The value must be too large (a positive value of a large value or positive infinity), and the result of the first step is the largest representable value of type int or long.

byte , char and short :

If the target type is byte , char or short , the conversion is two-stage. First, double converted to long , as described above. Then long converted to the final type as follows:

Narrowing the conversion of a signed integer to an integral type T simply discards everything except n bits of the least significant bit, where n is the number of bits used to represent type T. In addition to the possible loss of information about the value, a numerical value can lead to the sign of the resulting values โ€‹โ€‹will differ from the sign of the input value.

+4
source

Source: https://habr.com/ru/post/915065/


All Articles