I have the following code:
Double i=17.31; long j=(long) (i*100); System.out.println(j);
O/P : 1730 //Expected:1731
Double i=17.33; long j=(long) (i*100); System.out.println(j);
O/P : 1732 //Expected:1733
Double i=17.32; long j=(long) (i*100); System.out.println(j);
O/P : 1732 //Expected:1732{As expected}
Double i=15.33; long j=(long) (i*100); System.out.println(j);
O/P : 1533 //Expected:1533{as Expected}
I have tried to Google but unable to find reason.I am sorry if the question is trivial.
None of the answers seem to deal with why 17.32
acted different.
The difference in behaviour you see between 17.32
and 17.33 & 17.31
is due to IEEE-754 Rounding rules.
Rounding rule applied: from, The Java™ Virtual Machine Specification §2.8.1
The rounding operations of the Java virtual machine always use IEEE 754 round to nearest mode. Inexact results are rounded to the nearest representable value, with ties going to the value with a zero least-significant bit. This is the IEEE 754 default mode. The Java virtual machine does not give any means to change the floating-point rounding mode
Double is: (1 sign-bit + 11 exponent-bits + 52 fraction-bits = 64bits). Internal representation after rounding below:
1 [63] 11 [62-52] 52 [51-00] Sign Exponent Fraction 17.31 --> 0 (+) 10000000011 (+4) 1.0001010011110101110000101000111101011100001010001111 17.32 --> 0 (+) 10000000011 (+4) 1.0001010100011110101110000101000111101011100001010010 //rounded up 17.33 --> 0 (+) 10000000011 (+4) 1.0001010101000111101011100001010001111010111000010100
17.31: (Mantissa comparison)
Actual: 1.00010100111101011100001010001111010111000010100011110... Internal: 1.0001010011110101110000101000111101011100001010001111
17.32: (Mantissa comparison)
Actual: 1.00010101000111101011100001010001111010111000010100011... Internal: 1.0001010100011110101110000101000111101011100001010010 //round-up!
17.33: (Mantissa comparison)
Actual: 1.00010101010001111010111000010100011110101110000101000... Internal: 1.0001010101000111101011100001010001111010111000010100
17.31 -> 17.309999999999998721023075631819665431976318359375... 17.32 -> 17.32000000000000028421709430404007434844970703125... //(was rounded up) 17.33 -> 17.3299999999999982946974341757595539093017578125...
(IEEE-754 Analysis Tool)
EDIT: There is a factor more at play at your multiplication step as @Jeppe Stig Nielsen said. The result of the FP multiplication (Reference) step does its own rounding-towards-nearest. This changes which results are as expected and which aren't, but the reason is still exactly the same as stated above.
Finally, due to the cast (long)
, truncation occurs, and leaves you with the results you see. (1730, 1732, 1732)
Narrowing Primitive Conversion : The Java™ Language Specification §5.1.3
If the floating-point number is not an infinity, the floating-point value is rounded to an integer value V, rounding toward zero using IEEE 754 round-toward-zero mode
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With