Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid scientific notation for large numbers in JavaScript?

Tags:

javascript

People also ask

How do you handle large numbers in JavaScript?

To represent integers larger than 2 to the 53rd power minus 1 in JavaScript, we can use the BigInt object to represent the values. It can be manipulated via normal operations like arithmetic operators — addition, subtraction, multiplication, division, remainder, and exponentiation.

How do you get rid of scientific notation in numbers?

(1) Right-click a cell where you want to remove scientific notation, and (2) choose Format Cells… 2. In the Format Cells window, (1) select the Number category, (2) set the number of decimal places to 0, and (3) click OK. Now the scientific notation is removed.

How do you convert an exponential number to JavaScript?

To parse and convert exponential values to decimal in JavaScript, we can use the toFixed method. to call toFixed on 4.656657507739E-10 and return a number with 20 decimal places. Therefore, n is 0.00000000046566575077. toFixed can parse numbers that has up to 20 decimal places.


There's Number.toFixed, but it uses scientific notation if the number is >= 1e21 and has a maximum precision of 20. Other than that, you can roll your own, but it will be messy.

function toFixed(x) {
  if (Math.abs(x) < 1.0) {
    var e = parseInt(x.toString().split('e-')[1]);
    if (e) {
        x *= Math.pow(10,e-1);
        x = '0.' + (new Array(e)).join('0') + x.toString().substring(2);
    }
  } else {
    var e = parseInt(x.toString().split('+')[1]);
    if (e > 20) {
        e -= 20;
        x /= Math.pow(10,e);
        x += (new Array(e+1)).join('0');
    }
  }
  return x;
}

Above uses cheap-'n'-easy string repetition ((new Array(n+1)).join(str)). You could define String.prototype.repeat using Russian Peasant Multiplication and use that instead.

This answer should only be applied to the context of the question: displaying a large number without using scientific notation. For anything else, you should use a BigInt library, such as BigNumber, Leemon's BigInt, or BigInteger. Going forward, the new native BigInt (note: not Leemon's) should be available; Chromium and browsers based on it (Chrome, the new Edge [v79+], Brave) and Firefox all have support; Safari's support is underway.

Here's how you'd use BigInt for it: BigInt(n).toString()

Example:

const n = 13523563246234613317632;
console.log("toFixed (wrong): " + n.toFixed());
console.log("BigInt (right):  " + BigInt(n).toString());

Beware, though, that any integer you output as a JavaScript number (not a BigInt) that's more than 15-16 digits (specifically, greater than Number.MAX_SAFE_INTEGER + 1 [9,007,199,254,740,992]) may be be rounded, because JavaScript's number type (IEEE-754 double-precision floating point) can't precisely hold all integers beyond that point. As of Number.MAX_SAFE_INTEGER + 1 it's working in multiples of 2, so it can't hold odd numbers anymore (and similiarly, at 18,014,398,509,481,984 it starts working in multiples of 4, then 8, then 16, ...).

Consequently, if you can rely on BigInt support, output your number as a string you pass to the BigInt function:

const n = BigInt("YourNumberHere");

Example:

const n1 = BigInt(18014398509481985); // WRONG, will round to 18014398509481984
                                      // before `BigInt` sees it
console.log(n1.toString() + " <== WRONG");
const n2 = BigInt("18014398509481985"); // RIGHT, BigInt handles it
console.log(n2.toString() + " <== Right");

I know this is an older question, but shows recently active. MDN toLocaleString

const myNumb = 1000000000000000000000;
console.log( myNumb ); // 1e+21
console.log( myNumb.toLocaleString() ); // "1,000,000,000,000,000,000,000"
console.log( myNumb.toLocaleString('fullwide', {useGrouping:false}) ); // "1000000000000000000000"

you can use options to format the output.

Note:

Number.toLocaleString() rounds after 16 decimal places, so that...

const myNumb = 586084736227728377283728272309128120398;
console.log( myNumb.toLocaleString('fullwide', { useGrouping: false }) );

...returns...

586084736227728400000000000000000000000

This is perhaps undesirable if accuracy is important in the intended result.


For small number, and you know how many decimals you want, you can use toFixed and then use a regexp to remove the trailing zeros.

Number(1e-7).toFixed(8).replace(/\.?0+$/,"") //0.000

one more possible solution:

function toFix(i){
 var str='';
 do{
   let a = i%10;
   i=Math.trunc(i/10);
   str = a+str;
 }while(i>0)
 return str;
}

Here is my short variant of Number.prototype.toFixed method that works with any number:

Number.prototype.toFixedSpecial = function(n) {
  var str = this.toFixed(n);
  if (str.indexOf('e+') === -1)
    return str;

  // if number is in scientific notation, pick (b)ase and (p)ower
  str = str.replace('.', '').split('e+').reduce(function(b, p) {
    return b + Array(p - b.length + 2).join(0);
  });
  
  if (n > 0)
    str += '.' + Array(n + 1).join(0);
  
  return str;
};

console.log( 1e21.toFixedSpecial(2) );       // "1000000000000000000000.00"
console.log( 2.1e24.toFixedSpecial(0) );     // "2100000000000000000000000"
console.log( 1234567..toFixedSpecial(1) );   // "1234567.0"
console.log( 1234567.89.toFixedSpecial(3) ); // "1234567.890"