1

I am creating a BigDecimal from a double value of 0.495, and printing it to two decimal digits with HALF_UP rounding mode. Here's the code:

BigDecimal d = new BigDecimal(0.495);
d = d.setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println(d.toPlainString());

I am expecting to see 0.50 as the result, but I am seeing 0.49 instead. ROUND_HALF_UP should round up if the discarded fraction is >= .5.

So why am I seeing this behaviour?

Samurai Jack
  • 2,985
  • 8
  • 35
  • 58
Grodriguez
  • 21,501
  • 10
  • 63
  • 107
  • 1
    Bear in mind that if you start with a double `0.495`, you're already approximating, before the `BigDecimal` is even instantiated. What if you start with `"0.495"` instead? – khelwood May 15 '17 at 11:46
  • When you use 0.495 you actually get 0.49499999999999999555910790149937383830547332763671875 – Dia May 15 '17 at 11:50
  • Related: http://stackoverflow.com/questions/3693014/bigdecimal-from-double-incorrect-value – Mark Dickinson May 15 '17 at 11:51
  • In other words: if you want to initialize a BigDecimal to an exact decimal value, **NEVER** use a double. Use a string, if you can. – Rudy Velthuis May 16 '17 at 09:28

1 Answers1

3

When you write

new BigDecimal(0.495)

you are passing a double value to the BigDecimal constructor. Double values are approximations. In this case, your BigDecimal instance has a value a little under 0.495 from the point it is instantiated.

If you pass a string instead of a double, the BigDecimal will represent the exact value indicated by the string.

So use

BigDecimal d = new BigDecimal("0.495");
khelwood
  • 55,782
  • 14
  • 81
  • 108