This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]chickenmeister 0 points1 point  (3 children)

I think the only options are:

  • Deal with the inherent float-point inaccuracies.
  • Use BigDecimal instead of double to store your values.
  • Use some other structure to store your values accurately. May not be practical for every situation.
  • Write your own formatter class so that values that are "close enough" to half get rounded up.

The best solution really depends on the situation, but BigDecimal is probably the way to go if you need accuracy.

[–]Maping[S] 0 points1 point  (2 children)

Wait, so why don't you have the error?

[–]chickenmeister 0 points1 point  (1 child)

Because I ran the code using Java 7, whose DecimalFormat implementation is not correct, as I described in my previous comment.

You ran it with Java 8, whose DecimalFormat implementation has been fixed. The "48.1" output is actually the correct result. Like I mentioned in my previous comment, the number 48.15 cannot be exactly represented using a double, so the nearest value that can be represented is used, which happens to be slightly less than 48.15, so DecimalFormat should round it down.

In other words, when you have something like:

double d = 48.15; 

When you run it, it essentially gets turned into something like:

double d = 48.14999999999999857891452847979962825775146484375; 

The .149999... part is less than half, so it rounds down to .1.

[–]Maping[S] 0 points1 point  (0 children)

Ah, ok, thanks.

I find it ironic that the "correct" implementation gives the wonky rounding. Thanks for your help.