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.
Rules for Rounding-off a NumberDiscard all digits to the right of nth significant digit. less than half a unit in nthplace, leave the nth digit unchanged. greater than half a unit in the nth place, increase the nth digit by unity.
We round a number to three significant figures in the same way that we would round to three decimal places. We count from the first non-zero digit for three digits. We then round the last digit. We fill in any remaining places to the right of the decimal point with zeros.
If you are rounding a number to a certain degree of significant digits, and if the number following that degree is less than five the last significant figure is not rounded up, if it is greater than 5 it is rounded up.
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; }
Here's a short and sweet JavaScript implementation:
function sigFigs(n, sig) { var mult = Math.pow(10, sig - Math.floor(Math.log(n) / Math.LN10) - 1); return Math.round(n * mult) / mult; } alert(sigFigs(1234567, 3)); // Gives 1230000 alert(sigFigs(0.06805, 3)); // Gives 0.0681 alert(sigFigs(5, 3)); // Gives 5
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With