0

I want to round off the numbers to 2 digits only, have written the below code:

Double input = 17.755;
DecimalFormat twoDigitDecimalFormat = new DecimalFormat("0.00");
Double output = Double.valueOf(twoDigitDecimalFormat.format(input));

I was expecting output should be 17.76 but it is giving me 17.75 only, for all the other cases it is working perfectly fine, but only this number is not working, if I add one more digit in the input, say 17.7551 then it will roundoff to 17.76

Abdul Mohsin
  • 1,253
  • 1
  • 13
  • 24
  • 1
    [read the documentation](https://docs.oracle.com/javase/7/docs/api/java/text/DecimalFormat.html) – mr mcwolf Feb 15 '23 at 06:29
  • 1
    For your example, `17.751` does not round to `17.76` did you mean `17.7551`? As pointed out in a comment below. `input` is not exactly `17.755` it is the closest value that double can represent. `17.75499...` if you want better accuracy there is [BigDecimal](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/math/BigDecimal.html). eg `new BigDecimal("17.755");` That way you'll be rounding what you expect. – matt Feb 15 '23 at 09:34
  • Sorry @matt the input was 17.7551 , ive corrected that in the description also – Abdul Mohsin Feb 19 '23 at 08:04
  • you can change rounding mode if you need ceiling : https://stackoverflow.com/questions/153724/how-to-round-a-number-to-n-decimal-places-in-java – bardia dorry Feb 19 '23 at 10:55

1 Answers1

1

First of, your final value is a Double it does not have 2 digits! When you do Double.valueOf it will become the closest representable value. If you actually want two digits in Java then you need to use BigDecimal which actually stores base 10 floating point representations.

The trick is, the value you are using is not what you think it is.

double d = 17.755;

Java doubles are power of 2 exponent, so a number that appears to be an exact value in decimal, has a repeating representation in float. That means it needs to be truncated and the closest value is used.

jshell> double d = 17.755;
d ==> 17.755

jshell> var x = new BigDecimal(d);
x ==> 17.754999999999999005240169935859739780426025390625

jshell> var y = new BigDecimal("17.755");
y ==> 17.755

Now you can see that x which is an exact representation of d is actually less than 17.755 so when you round it it goes down.

y on the other hand is exactly 17.755 and will round according the the rules you apply.

jshell> System.out.printf("%.2f\n", y);
17.76

jshell> System.out.printf("%.2f\n", x);
17.75
matt
  • 10,892
  • 3
  • 22
  • 34