1

I have been sitting on this for a day now thinking like a 5th grade school student.

public class Tester 
{                                                          
    static String actualValue = "";
    private static DecimalFormat df2 = new DecimalFormat("#.##");  //To round off to two decimal places.
    static double regPrice = 0.0;
    static double regPrice2 = 0.0;
    
     public static void main(String[] args) 
     {
          regPrice2 = 1506.365;
          
          System.out.println("reg price 1 is: "+regPrice2);
          System.out.println("reg price 1 after rounding is is: "+round(regPrice2));
          
          regPrice = 8535.765;
          
          System.out.println("reg price  is: "+regPrice);
          System.out.println("reg price  after rounding is: "+round(regPrice));
      }
     
     public static double round(double value) 
        {         
            df2.setRoundingMode(RoundingMode.HALF_UP);
            String returnValue = df2.format(value);
            double actualValue = Double.parseDouble(returnValue);
            return actualValue;   
        }
    
}    
Output Value 1 Value 2
Actual 1506.37 8535.76
Expected 1506.37 8535.77

Why is the rounding off working for the first number but not the second? How can I make this work?

Fildor
  • 11,419
  • 4
  • 29
  • 57
Afsal
  • 133
  • 1
  • 14
  • 4
    (Unrelated) [Do not use floating point types for monetary amounts.](https://stackoverflow.com/q/3730019/982149) – Fildor Dec 16 '20 at 07:32
  • What is the output of line `System.out.println("reg price is: "+regPrice);` ? – Fildor Dec 16 '20 at 07:41
  • reg price 1 is: 1506.365 reg price 1 after rounding is is: 1506.37 reg price is: 8535.765 reg price after rounding is: 8535.76 – Afsal Dec 16 '20 at 08:07
  • Is it _really_? I'd expect it to be 8535.76499999999999999999995874871 or something like that. – Fildor Dec 16 '20 at 08:29
  • I get your value when I do regPrice2 = new BigDecimal(1506.365); But when I use double, it prints 8535.765 – Afsal Dec 16 '20 at 08:37

1 Answers1

1

Thank to the floating-pointrepresentation, what you think 1506.365 or 8535.765 is actually number slightly greater or less than you expect. The floating-point numbers are represented as mantissa and exponent. Hence for example for 0.365 and 0.765 rounding is done differently. Rounding near halves then appears as in random direction. Use BigDecimal if you need a precise number.

user207421
  • 289,834
  • 37
  • 266
  • 440
Tomáš Záluský
  • 6,234
  • 1
  • 26
  • 49
  • This is interesting. regPrice2 = new BigDecimal(1506.365); regPrice = new BigDecimal(8535.765); prints : ``` reg price 1 is: 1506.365000000000009094947017729282379150390625 reg price 1 after rounding is is: 1506.37 reg price is: 8535.764999999999417923390865325927734375 reg price after rounding is: 8535.76 ``` My requirement is to get 8535.76. How to achieve that? – Afsal Dec 16 '20 at 08:39
  • Your comment combined with the suggestions in https://stackoverflow.com/questions/7124448/how-does-java-math-roundingmode-work gave me the solution. Thanks. :) – Afsal Dec 16 '20 at 08:59