shandor
shandor

Reputation: 53

Format fractional percent in java yields very strange behaviour

I am trying to format percentages with the following code:

NumberFormat fmt = NumberFormat.getPercentInstance();
fmt.setRoundingMode(RoundingMode.HALF_UP);
fmt.setMinimumFractionDigits(0);
fmt.setMaximumFractionDigits(0);
System.out.println(fmt.format(0.145));

However, I get a very strange result:

14%

Changing the value 0.145 to something else, for example 0.125 will work properly and the result will be as expected

13%

Can someone shed some light on this? Thanks in advance

Upvotes: 1

Views: 202

Answers (3)

Chris Dodd
Chris Dodd

Reputation: 126203

You should read What Every Computer Scientist Should Know About Floating-Point Arithmetic, but basically it comes down to the fact that .145 can't be exactly represented in IEEE floating point, and so gets rounded to the nearest value that can be represented, which just happens to be slightly less that .145, so it gets rounded down when rounded to two digits.

Upvotes: 1

jcklie
jcklie

Reputation: 4094

I think that is an result of the intern representation of floats. (Decimal numbers represented by binary numbers).

Your 0.145 might be internally represented as 0.144999999999..., so rounding mode rounds down.

Upvotes: 1

Louis Wasserman
Louis Wasserman

Reputation: 198073

This is due to the inherent rounding error in double, resulting in 0.145 being rounded to

0.1449999999999999900079927783735911361873149871826171875

Use BigDecimal if you expect perfect accuracy.

Upvotes: 1

Related Questions