1

I have a number with value

0.947

Now, I use DecimalFormat API of java.text with the following pattern and RoundingMode-

double numberToFormat = 0.947;    
DecimalFormat restrictTo1DecimalPlace = new DecimalFormat("0.0%");
restrictTo1DecimalPlace.setRoundingMode(RoundingMode.DOWN);
String formattedString = restrictTo2DecimalPlace.format(numberToFormat);

Now, I was expecting the value of formattedString to be 94.7% but its 94.6%. I know the value has been set to RoundMode.Down but then why does value of following are not rounded down -

  • 0.9471 -> 94.7%
  • 0.9447 -> 94.4%
Vitalii Pro
  • 313
  • 2
  • 17
Vishal
  • 666
  • 1
  • 8
  • 30
  • check this link (https://docs.oracle.com/javase/7/docs/api/java/math/RoundingMode.html). It clearly explained – murthy Jul 21 '17 at 16:00
  • Checked it already, I don't know still – Vishal Jul 21 '17 at 16:01
  • May be I need to understand Rounding down better but I was asking that why value of 0.9471 is 94.7% and not 94.6% like the earlier example in question – Vishal Jul 21 '17 at 16:04
  • It's not rounding you need to understand better, but the behaviour of floating point numbers. – Bathsheba Jul 21 '17 at 16:05

1 Answers1

11

The closest floating point number to 0.947 is actually

0.94699999999999995292654375589336268603801727294921875

This is what your computer stores as a double when you write 0.947.

Rounding that down gives you 94.6%.

That's life I'm afraid. If you want exact decimal behaviour then use a decimal type! See data type to represent a big decimal in java

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • `If you want exact decimal behaviour then use a decimal type!` Can you elaborate this please? – Vishal Jul 21 '17 at 16:05
  • @Vishal: I've added a link to an SO question that contains more information on this. – Bathsheba Jul 21 '17 at 16:06
  • 2
    @Aaron: But do be careful to use the string constructor to `BigDecimal` else you're back where you started. – Bathsheba Jul 21 '17 at 16:10
  • @Bathsheba I've avoided constructing the `BigDecimal` from a `double` which would have been problematic. Is using the `String` constructor over `BigDecimal` arithmetics preferred? I hardly ever use them so I really don't know the best practices – Aaron Jul 21 '17 at 16:16
  • @Aaron: I don't use `BigDecimal` either - as a scientific programmer I'm more than happy with binary floating point. – Bathsheba Jul 21 '17 at 16:18