0

This is a sample piece of code I am trying. I know that it is because of double precision/roundoff. But let me know exactly what is happening and how to overcome it.?

public class DoubleSample {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        double price1 = 16.99;
        double price2 = 12.99;
        int multiplier =10000;

        double price1updated = price1 * multiplier;
        double price2updated = price2 * multiplier;

        System.out.println("price1 "+price1updated);
        System.out.println("price2 "+price2updated);
    }

}

The output is

price1 169899.99999999997
price2 129900.0
Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555

1 Answers1

2

That's because a double represents a decimal number with radix two, and 10 is not a power of 2. This means that for certain values, the double equivalent will differ.

There are two ways to solve this issue:

  • Use a BigDecimal; or
  • Round the result up to the number of digits "repairing" the double yourself.

You can use a BigDecimal to solve this problem. In that case the code would read something like:

BigDecimal price1 = new BigDecimal("16.99");
BigDecimal price2 = new BigDecimal("12.99");
BigDecimal multiplier = new BigDecimal(10000);

BigDecimal price1updated = price1.multiply(multiplier);
BigDecimal price2updated = price2.multiply(multiplier);

System.out.println("price1 "+price1updated);
System.out.println("price2 "+price2updated);

Or, you can round off the errors, by rounding results off to for instance two significant digits. Now there is a tiny chance if you do this with large numbers, that the result will not be correct, (for instance if the multiplier is greater than 1G). In case you want to round off on two digits, the code reads:

double price1 = 16.99;
double price2 = 12.99;
int multiplier =10000;

double price1updated = Math.round(price1 * multiplier * 100.0d)*0.01d;
double price2updated = Math.round(price2 * multiplier * 100.0d)*0.01d;

System.out.println("price1 "+price1updated);
System.out.println("price2 "+price2updated);

There is however no guarantee this will always help and as already said, it is possible the result will be a few cents more or less (but only on large numbers, so the relative error is very small).

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555