1

I want to get the result with round the value please see the attached image. What is wrong with it.

The result should be : 18.59

round problem

I have used float instead of double.

MRE:

    float value = 18.585f;
    System.out.println(((float)Math.round(value * 100))/100);

Observed output:

18.58

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
Chirag Prajapati
  • 337
  • 6
  • 14
  • 2
    System.out.println((float)Math.round(18.585*100)/100); Returning 18.59 for me – DKS Aug 03 '21 at 07:30
  • 1
    double value = 18.585; System.out.println(((double)Math.round(value * 100))/100); prints 18,59.......... float value = 18.585f; System.out.println(((double)Math.round(value * 100))/100); prints 18,58 – Petr F. Aug 03 '21 at 07:36
  • 1
    @Petr F. I have used float instead of double. – Chirag Prajapati Aug 03 '21 at 07:40
  • with float I get same results:double value = 18.585; System.out.println(((float)Math.round(value * 100))/100); prints 18,59.......... float value = 18.585f; System.out.println(((float)Math.round(value * 100))/100); prints 18,58 – Petr F. Aug 03 '21 at 07:48
  • I downvoted because you didn’t paste your code as text and because you didn’t give us a [mre]. It’s good that you have given us the expected result. We also need the observed result. – Ole V.V. Aug 03 '21 at 07:57
  • you just need to make sure value in *value* is double as @PetrF mention before. – Gg M Aug 03 '21 at 07:59
  • Does this answer your question? [Is floating point math broken?](https://stackoverflow.com/questions/588004/is-floating-point-math-broken) – Ole V.V. Aug 03 '21 at 08:01
  • @Ole V.V. I have not got any solution yet. Can you please help me to get 18.59 as a result. What should I do? – Chirag Prajapati Aug 03 '21 at 08:38
  • I got the solution by applying the BigDecimal. Thanks buddy I appreciate your effort. Thank you. Have great life ahead. – Chirag Prajapati Aug 07 '21 at 03:15

1 Answers1

1

The problem

The problem is not in the rounding. The problem is in the value that you are rounding. You think the value is 18.585. It is not. float values are not precise. The real value in your float variable is somewhere around 18.584999 because a float hasn’t got a better precision. The correct rounding of this value to two decimal places is 18.58. The result you got.

(Except you got 18.5799999237060546875 because the new value isn’t precise either; but in printed as 18.58.)

A couple of possible solutions

The solution? There are many. I will present two.

  1. Add a small value (sometimes referred to as an epsilon) to your value before rounding.
  2. Use BigDecimal instead of float.

Add an epsilon

Let’s declare:

private static final float EPSILON = 0.000_001f;

And use it:

    float value = 18.585f;
    System.out.println(((float) Math.round((value + EPSILON) * 100)) / 100);

Output is the desired:

18.59

For values not ending in 5 adding the epsilon will not make any change to the rounded value, so only in weird corner cases does this approach risk giving undesired results.

Use BigDecimal

A BigDecimal holds the full precision of a decimal number no matter how many decimals you give it.

    BigDecimal value = new BigDecimal("18.585");
    BigDecimal roundedValue = value.setScale(2, RoundingMode.HALF_UP);
    System.out.println(roundedValue);
18.59

I am specifying RoundingMode.HALF_UP to make sure that rounding of 18.585 goes up to 18.59, not down to 18.58.

It’s crucial to use the constructor that takes a String argument so we also pass the full precision of your number into the BigDecimal. If we just passed the float to the BigDecimal, the imprecision would go along. Just to deter you, see how this fails:

    BigDecimal value = new BigDecimal(18.585f);
    System.out.println(value);
    BigDecimal roundedValue = value.setScale(2, RoundingMode.HALF_UP);
    System.out.println(roundedValue);
18.58499908447265625
18.58

It was suggested in the comments that you could use double instead of float. double has a much better precision. Actually float has got a bad reputation. double still isn’t fully precise, so while they seem to fix the problem with 18.585, you risk running into the same problem with some other value.

Link

Related question with a lot of good information: Is floating point math broken?

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161