简体   繁体   中英

How the explicit cast from double to int rounds in Java?

System.out.println((int)(99.9999999999999));

returns 99

System.out.println((int)(99.999999999999999999999999999999999999999));

returns 100

Can you explain me why?

The double literal 99.9999999999999 can be represented as a double which is less than 100 , so the cast to int truncates the decimal part and 99 is the result.

The double literal 99.999999999999999999999999999999999999999 has the closest actual value of 100 , and casting to int is simply 100 here.

System.out.println(99.9999999999999);
System.out.println((int)(99.9999999999999));
System.out.println(99.9999999999999 == 100.0);

System.out.println(99.999999999999999999999999999999999999999);
System.out.println((int)(99.999999999999999999999999999999999999999));
System.out.println(99.999999999999999999999999999999999999999 == 100.0);

I used 100.0 as a double literal here, to compare 2 double values to see if they are the exact same double value.

This prints out:

99.9999999999999
99
false
100.0
100
true

The JLS, Section 3.10.2 covers floating point literals:

The details of proper input conversion from a Unicode string representation of a floating-point number to the internal IEEE 754 binary floating-point representation are described for the methods valueOf of class Float and class Double of the package java.lang.

And Double.valueOf javadocs state:

Otherwise, s is regarded as representing an exact decimal value in the usual "computerized scientific notation" or as an exact hexadecimal value; this exact numerical value is then conceptually converted to an "infinitely precise" binary value that is then rounded to type double by the usual round-to-nearest rule of IEEE 754 floating-point arithmetic, which includes preserving the sign of a zero value.

(emphasis mine)

That is, the value is rounded to produce the actual double value.

Parsing a floating point value occurs at compile time. The javac compiler rounds the value to 100 before it ever emits any code into your .class file, because the most accurate representation of the number you wrote is not 99.9999999999 but 100: You're .0000000000099999999 closer to 100 than you are to 99.999999999 (I was probably inconsistent with my number of digits there). I wrote something that might help you on the .NET Code Generation blog . Nothing I wrote applies any differently to Java than it does to C# (or C++ or any other language that uses floating point)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM