Search code examples
algorithmroundingsignificant-digits

Rounding to an arbitrary number of significant digits


How can you round any number (not just integers > 0) to N significant digits?

For example, if I want to round to three significant digits, I'm looking for a formula that could take:

1,239,451 and return 1,240,000

12.1257 and return 12.1

.0681 and return .0681

5 and return 5

Naturally the algorithm should not be hard-coded to only handle N of 3, although that would be a start.


Solution

  • Here's the same code in Java without the 12.100000000000001 bug other answers have

    I also removed repeated code, changed power to a type integer to prevent floating issues when n - d is done, and made the long intermediate more clear

    The bug was caused by multiplying a large number with a small number. Instead I divide two numbers of similar size.

    EDIT
    Fixed more bugs. Added check for 0 as it would result in NaN. Made the function actually work with negative numbers (The original code doesn't handle negative numbers because a log of a negative number is a complex number)

    public static double roundToSignificantFigures(double num, int n) {
        if(num == 0) {
            return 0;
        }
    
        final double d = Math.ceil(Math.log10(num < 0 ? -num: num));
        final int power = n - (int) d;
    
        final double magnitude = Math.pow(10, power);
        final long shifted = Math.round(num*magnitude);
        return shifted/magnitude;
    }