Reputation: 5964
Why does the following code:
System.out.println((int)(19.99 * 100));
produce the result "1998"?
Upvotes: 5
Views: 322
Reputation: 533442
That is because 19.99 cannot be represented exactly.
System.out.println(new BigDecimal(19.99));
prints the value this actually represents which is the closest to 19.99 it can represent.
19.989999999999998436805981327779591083526611328125
and 19.99 * 100
is
System.out.println(new BigDecimal(19.99 * 100));
which is
1998.999999999999772626324556767940521240234375
The problem is that you have a representation error in 19.99 which is still there when multiplied by 100 you get a number which is slightly too small.
if you multiply by 100 and round down which is what (int)
does you should expect to get 1998.
An alternative is
System.out.println(Math.round(19.99 * 100));
Upvotes: 5
Reputation: 20254
Floating point data types (float and double in Java) can only approximately represent most decimal values. See Joshua Bloch's words of wisdom on the subject for more details.
Upvotes: 1
Reputation: 20583
System.out.println((19.99 * 100));
produces the result 1998.9999999999998 by adding int casting it truncates the fraction part and returns 1998
Upvotes: 1
Reputation: 52185
It is due to a rounding issues. double
and float
are prone to these issues, which is why it is recommended you use the BigDecimal
class.
This code should print what is expected:
BigDecimal bg = new BigDecimal("19.99");
System.out.println(bg.multiply(new BigDecimal("10")));
This yields:
199.90
Upvotes: 1
Reputation: 72254
Rounding errors. If you look at the result of your calculation without the cast, you get:
1998.9999999999998
So when you cast to int, the decimal part is dropped, not rounded up, and you get 1998.
The moral is, if you need an exact answer, don't use float / double at all. If you're talking about a discrete value like money, use int and deal with the atomic unit (eg. pence.) If you do need exact decimals, then BigDecimal
is your friend.
While you can bodge the result here using Math.round()
to bring the result to where it's expected, this won't work in all cases and fails to address the underlying issue.
Upvotes: 9
Reputation: 26418
because the calculation of 19.99 * 100 will result in 1998.999999 and you are casting it to int it will discard the fractional part of it.
Upvotes: 1