Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Casting a double to another numeric type

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:

  1. float: Infinity
  2. int: 2147483647
  3. short: -1
  4. 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 ?

like image 307
Jerome Avatar asked May 07 '12 07:05

Jerome


People also ask

Can integer be cast to double?

We can convert int value to Double object by instantiating Double class or calling Double. valueOf() method.

Can you cast a double in Java?

In Java when you cast you are changing the “shape” (or type) of the variable. The casting operators (int) and (double) are used right next to a number or variable to create a temporary value converted to a different data type. For example, (double) 1/3 will give a double result instead of an int one.

How do you cast data types?

A data type that can be changed to another data type is castable from the source data type to the target data type. The casting of one data type to another can occur implicitly or explicitly. The cast functions or CAST specification (see CAST specification) can be used to explicitly change a data type.

How do you change a number to a double in Java?

you can use java. lang. Number. doubleValue() method to cast a number to a double object.


1 Answers

JLS spells out the rules in section 5.1.3 Narrowing Primitive Conversion. The rules depend on the target type.

float:

A narrowing primitive conversion from double to float is governed by the IEEE 754 rounding rules (§4.2.4). This conversion can lose precision, but also lose range, resulting in a float zero from a nonzero double and a float infinity from a finite double. A double NaN is converted to a float NaN and a double infinity is converted to the same-signed float infinity.

int and long:

one of the following two cases must be true:

  • ...
  • The value must be too large (a positive value of large magnitude 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 it two-step. First, the double is converted to long as explained above. Then, the long is converted to the final type as follows:

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.

like image 56
NPE Avatar answered Oct 14 '22 09:10

NPE