Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unexpected result of java calculation

Tags:

java

Why does the following code:

System.out.println((int)(19.99 * 100));

produce the result "1998"?

like image 925
Mark W Avatar asked Dec 01 '22 21:12

Mark W


2 Answers

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.

like image 160
Michael Berry Avatar answered Dec 13 '22 06:12

Michael Berry


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));
like image 36
Peter Lawrey Avatar answered Dec 13 '22 06:12

Peter Lawrey