Mark W
Mark W

Reputation: 5964

Unexpected result of java calculation

Why does the following code:

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

produce the result "1998"?

Upvotes: 5

Views: 322

Answers (6)

Peter Lawrey
Peter Lawrey

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

codebox
codebox

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

Dungeon Hunter
Dungeon Hunter

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

npinti
npinti

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

Michael Berry
Michael Berry

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

GuruKulki
GuruKulki

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

Related Questions