Reputation: 1094
System.out.println((int)(99.9999999999999));
returns 99
System.out.println((int)(99.999999999999999999999999999999999999999));
returns 100
Can you explain me why?
Upvotes: 3
Views: 421
Reputation: 178303
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.
Upvotes: 5
Reputation: 416
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)
Upvotes: 1