Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Opposite of Number.toExponential in JS

I need to get the value of an extremely large number in JavaScript in non-exponential form. Number.toFixed simply returns it in exponential form as a string, which is worse than what I had.

This is what Number.toFixed returns:

>>> x = 1e+31
1e+31
>>> x.toFixed()
"1e+31"

Number.toPrecision also does not work:

>>> x = 1e+31
1e+31
>>> x.toPrecision( 21 )
"9.99999999999999963590e+30"

What I would like is:

>>> x = 1e+31
1e+31
>>> x.toNotExponential()
"10000000000000000000000000000000"

I could write my own parser but I would rather use a native JS method if one exists.

like image 978
Oz. Avatar asked Nov 13 '10 02:11

Oz.


4 Answers

You can use toPrecision with a parameter specifying how many digits you want to display:

x.toPrecision(31)

However, among the browsers I tested, the above code only works on Firefox. According to the ECMAScript specification, the valid range for toPrecision is 1 to 21, and both IE and Chrome throw a RangeError accordingly. This is due to the fact that the floating-point representation used in JavaScript is incapable of actually representing numbers to 31 digits of precision.

like image 116
casablanca Avatar answered Sep 28 '22 13:09

casablanca


Use Number(string)

Example :

var a = Number("1.1e+2");

Return :

a = 110

like image 43
Erik Gustafsson Avatar answered Sep 28 '22 11:09

Erik Gustafsson


The answer is there's no such built-in function. I've searched high and low. Here's the RegExp I use to split the number into sign, coefficient (digits before decimal point), fractional part (digits after decimal point) and exponent:

/^([+-])?(\d+)\.?(\d*)[eE]([+-]?\d+)$/

"Roll your own" is the answer, which you already did.

like image 29
Gene Pavlovsky Avatar answered Sep 28 '22 11:09

Gene Pavlovsky


It's possible to expand JavaScript's exponential output using string functions. Admittedly, what I came up is somewhat cryptic, but it works if the exponent after the e is positive:

var originalNumber = 1e+31;
var splitNumber = originalNumber.toString().split('e');

var result;
if(splitNumber[1]) {
    var regexMatch = splitNumber[0].match(/^([^.]+)\.?(.*)$/);
    result =
        /* integer part */ regexMatch[1] +
        /* fractional part */ regexMatch[2] +
        /* trailing zeros */ Array(splitNumber[1] - regexMatch[2].length + 1).join('0');
} else result = splitNumber[0];
like image 43
PleaseStand Avatar answered Sep 28 '22 12:09

PleaseStand