While reading the answers to Nathan Smith’s JavaScript Quiz ,
I was struck by the number of assumptions made around decimal precision. In two places, the author states “you need to
multiply values by `10`

” when in actuality, you need to multiply values by the precision’s power of ten .

That lead me to write this bit of code to illustrate how you might handle high precision numbers (and of varying precision)
without using a separate library.

function getPrecision ( num ) {
var split = ( num + "" ). split ( / ([\. e \-]{1,2}) / );
var i , len , token , next , nextNum , precision ;
for ( precision = 0 , i = 1 , len = split . length ; i < len ; i += 1 ) {
token = split [ i ];
next = split [ i + 1 ];
nextNum = + next ;
if ( token === "." ) {
precision += next . length ;
} else if ( token === "e-" ) {
precision += i > 1 ? nextNum + 1 : nextNum ;
break ;
}
}
return precision ;
}
function getMaxPrecision ( arr ) {
var i , len , precision , max ;
for ( max = 0 , i = 0 , len = arr . length ; i < len ; i += 1 ) {
precision = getPrecision ( arr [ i ]);
max = ( precision > max ) ? precision : max ;
}
return max ;
}
function sumArgs () {
var args = Array . prototype . slice . call ( arguments );
var max = getMaxPrecision ( args );
var pow = Math . pow ( 10 , max );
var i , len , sum , arg ;
for ( sum = 0 , i = 0 , len = args . length ; i < len ; i += 1 ) {
arg = args [ i ];
sum += isNaN ( arg ) ? 0 : ( arg * pow );
}
return sum / pow ;
}
console . assert ( getPrecision ( 1 ) === 0 ); //no decimal or e-
console . assert ( getPrecision ( 1.1234567890 ) === 9 ); //zeros are dropped, just decimal
console . assert ( getPrecision ( 1.1234567890123456 ) === 16 ); //longest without rounding
console . assert ( getPrecision ( 0.1 ) === 1 );
console . assert ( getPrecision ( 0.12345678901234567 ) === 17 ); //longest without rounding
console . assert ( getPrecision ( 0.0000000001 ) === 10 ); //no decimal, just e-
console . assert ( getPrecision ( 0.00000000000000000000000000000000000000000000000000000123456789012345678 ) === 71 );
console . assert ( sumArgs ( 0.00002 , 0.00001 , 0.1 , 0.02 ) === 0.12003 );
console . assert ( getPrecision ( Math . min ()) === 0 ); //Infinity
console . assert ( getPrecision ( 1 e - 324 ) === 0 );
console . assert ( getPrecision ( 1 e - 323 ) === 323 );

EDIT: My use of Math.pow made me curious if there was a faster way to build a big number, see the tests:
http://jsperf.com/make-a-big-number/2