Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 899
DougN Avatar asked Oct 14 '08 18:10

DougN


People also ask

What are the rules to round off a number to n significant figures?

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.

How do you round to 3 significant figures?

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.

Can you round up significant figures?

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.


2 Answers

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; } 
like image 125
Pyrolistical Avatar answered Sep 17 '22 13:09

Pyrolistical


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 
like image 37
Ates Goral Avatar answered Sep 20 '22 13:09

Ates Goral