2

I have a nasty bug in an interest rate calculation: I have to round the answer to the nearest cent, but

interest = Math.round(interest * 100) / 100;

removes the entire decimal portion. interest is a double type. Why is this? The equivalent code works fine in C++.

Willy Wonka
  • 155
  • 5
  • 4
    The real bug is that you are using floating-point for money. Never do that. Use `BigDecimal`. – user207421 Jun 30 '17 at 09:56
  • I've had a look at the duplicate, but is it really that complicated to do a rounding? – Willy Wonka Jun 30 '17 at 09:57
  • Out of interest, what is your equivalent code in C++? We have ::floor and ::ceil, but not an "out of the box" German rounding function. – Bathsheba Jun 30 '17 at 09:57
  • Yes, it really is that complicated. The issue is as I stated there. Floating-point numbers don't have decimal places. They have binary places. If you want decimal places, use a decimal radix, i.e. `BigDecimal`. My answer there contains a complete refutation of the `*100/100` trick. It does not work. – user207421 Jun 30 '17 at 10:00

1 Answers1

3

Let's set aside the potentially greater issue of your using a binary floating point for a quantity that requires a precise decimal representation.

The Java bods broke with tradition and decided that Math.round(interest * 100) should return a long, rather than a double. (I imagine they did this since any double that is not an integer will be rounded to an integer that can fit into a long type). So the expression

Math.round(interest * 100) / 100

is evaluated in integer arithmetic, so any remainder is discarded. The clearest workaround in my opinion is to write

interest = Math.round(interest * 100) / 100.0;

which forces evaluation to take place in floating point.

Also note that the resultant underlying floating point value will, in general, have trailing non-zero digits past the 2nd decimal place even after this rounding has been applied: a double only gives you 15 decimal significant figures of precision.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483