2

I found that a rounding error with my Java application. The method used to round was:

 public static double round(double value,double precision)
    {
        return Math.round(value * precision) / precision;
    }

This could have an error (i.e. round(138.515,100) should return 138.52, and returns 138.51) So I've created the following rounder:

//  Mikeldi's rounder
public static double round2DecimalPlaces(double value,int decimalPlaces)
{
    int s = value<0?-1:1;
    double p = 1;
    for (int i = 0; i < decimalPlaces; i++) {
        p*=10;
    }

    double n = (long) value;
    double d = ((value*10*p)-(n*10*p));
    d +=s*5;
    d /= 10;
    d = (long)d;
    d /= p;
    return d+n;
}

I created this method since other rounding methods added too much latency to the system (low latency system). This one is around 10 times faster than the previous.

Note: This rounder will only use to round to possitive decimalPlaces (or 0).

Is there any problems I haven't see with this new rounder?

Thanks,

1
  • Is there any problems I haven't see with this new rounder? It depends what you want to achive... Fisrt of all you should write some unit test that will compare yours method output with the trusted method that you want to make run faster. And then look into everything that does not match and think about if those differences, if they exist, are acceptable or not. Commented Aug 14, 2013 at 11:19

1 Answer 1

11

The Math#round method is not broken. 138.515 can't be exactly represented as a double. To see the exact value, you can use:

System.out.println(new BigDecimal(138.515d));

which prints:

138.5149999999999863575794734060764312744140625

It is therefore accurate for round to return 138.51. If you need more precision than double can give, you can use BigDecimal.


EDIT

If BigDecimal is not an option, and if the number of decimals is smallish (say 3 or 4 because these are prices for example), you can use longs instead with the last 4 digits being the decimals. So 138.51d would be 1385100L instead.

Sign up to request clarification or add additional context in comments.

3 Comments

It adds too much lattency to the system
The numbers are actually prices, but different precisions need to be applied in different cases. Appart from that, we are using an external optimization algorithm that needs to use the prices as double.
@magodiez You can always pass doubles based on the longs to your external algo. But the bottom line is: double are not very precise and you will get rounding errors. That is the trade off for speed I'm afraid...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.