How does Double.intValue() work?

匿名 (未验证) 提交于 2019-12-03 08:33:39

问题:

This code

Double dbl = 254.9999999999999; Integer integ = dbl.intValue(); System.out.println(integ); 

shows 254, but one "9" more

Double dbl = 254.99999999999999; Integer integ = dbl.intValue(); System.out.println(integ); 

and it is already 255.. Why?

回答1:

To know the exact value of your double, you can use a BigDecimal:

System.out.println(new BigDecimal(254.9999999999999)); System.out.println(new BigDecimal(254.99999999999999)); 

prints:

254.9999999999998863131622783839702606201171875 255 

So this is simply due to (limitations of) double precision...



回答2:

System.out.println(254.9999999999999 == 255.0); System.out.println(254.99999999999999 == 255.0); 

prints

false true 

That should give you a hint. The double type can represent up to 16 significant digits, and your literal has 17. Therefore the double value nearest to the second decimal literal is 255.0.

For the second line of code, Eclipse actually issues a warning:

Comparing identical expressions

because it is already the compiler which is aware of the fact that these are just two literals for the exact same double value.



回答3:

A double is a 64-bit binary floating point representation of a number. Binary floating point numbers cannot exactly represent most decimal fractions. They can exactly represent 1/2, 1/4, 1/64+1/32 etc but they cannot exactly represent 0.9 or 0.1. Furthermore their precision is limited.

In your case, 254.99999999999999 has exactly the same representation as 255.0 internally. You can see this by checking a hexadecimal version of the binary fraction, using the Double.toHexString method. Because 254.99999999999999 is already equal to 255.0, when you cut off the fractional part by casting it to a 32-bit integer, you end up with 255.

System.out.println("a: " + Double.toHexString(254.99999999999999d)); System.out.println("b: " + Double.toHexString(255d)); 

Output

a: 0x1.fep7 b: 0x1.fep7 


回答4:

The answer is rather simple. The decimal number you wrote in your code with one 9 more is closer to the double which represents exactly 255 than any other double. So, the double that is used in the compilation is exactly equal to 255. While the decimal number with one 9 less is optimally represented with a double I show below. This means that it lies closer to that specific double than any other double.

Check out this demo: http://ideone.com/hSqJTJ

This is the output:

Original double: 254.9999999999999 Cast to int: 254 Exact double: 254.9999999999998863131622783839702606201171875  Original double: 255.0 Cast to int: 255 Exact double: 255 


回答5:

double binary format is sign (1) + exponent (11) + fraction (53). Binary form for 254.9999999999999 and 254.99999999999999 is

0 10000000110 1111110111111111111111111111111111111111111111111100 0 10000000110 1111111000000000000000000000000000000000000000000000 

we can get it as Long.toString(dbl.doubleToLongBits(dbl), 2);

integer part is

1111110 1111111 

leading 1 bit is omitted so actual integer values are

11111110 - 254 11111111 - 255 

note that cast double to integer is done not by rounding but truncation



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!