I had a brief moment of insight today that I thought I’d share with the world.
Nothing major, but quite useful.
Here’s how you round to significant digits in JavaScript…
Code
I created a function called Math.sig (see snippet below). By default it rounds to 2 significant digits.
/* Test cases:
alert(Math.sig(2515.7753));
alert(Math.sig(-593));
alert(Math.sig(315.152));
alert(Math.sig(3.14159265));
alert(Math.sig(13.141592));
alert(Math.sig(2 / 3));
alert(Math.sig(-2 / 3));
alert(Math.sig(0.0812));
alert(Math.sig(0));
alert(Math.sig(-0.005835, 3));
*/
Math.sig = function (num, sig) {
if (num == 0)
return 0;
if (Math.round(num) == num)
return num;
var digits = Math.round((-Math.log(Math.abs(num)) / Math.LN10) + (sig || 2)); //round to significant digits (sig)
if (digits < 0)
digits = 0;
return num.toFixed(digits);
}
Explanation
First of all, keen observers will note that the function doesn't actually do anything for numbers that have nothing after the decimal point (i.e. integers). This was intentional, because I personally don't find large integers with lots of digits to be as distracting as numbers with too many digits after the decimal point. Feel free to tweak this as you wish.
The most beautiful part of this is one function call:
Math.round((-Math.log(Math.abs(num)) / Math.LN10)
To determine the number of decimals, N, corresponding to D significant digits for any number X, it is necessary that we determine the magnitude of X in base 10 (or whatever base we wish to choose for our representation). The magnitude is computed using the logarithmic function. Then we know how many digits X consists of, and therefore we can then round to the right subset of those digits. Then, N = -log_10 |X| + D, where D = desired number of significant digits for rounding. For a small magnitude of X like 0.0003, we have a large value of -log_10|X| so we need to take more decimals to produce the same number of significant digits.
Now I will need to retrofit NETXPF's significant digits function with the same elegant formula. I can't believe I haven't thought of this before. I have come across the significant digits problem many times in the past, but only now found a simple mathematical formula to solve it. Now that I look at it, it almost seems too good to be true. Anyway, this is just another example of how seemingly complex problems can often have very simple solutions.
very cool & good tips and js code for beginners, thank you very much for sharing.