¿Cómo evitar la notación científica para números grandes en JavaScript?

Resuelto chris asked hace 15 años • 28 respuestas

JavaScript convierte números enteros con más de 21 dígitos a notación científica cuando se usa en un contexto de cadena. Estoy imprimiendo un número entero como parte de una URL. ¿Cómo puedo evitar que se produzca la conversión?

chris avatar Nov 06 '09 12:11 chris
Aceptado

Existe Number.toFixed , pero usa notación científica si el número es >= 1e21 y tiene una precisión máxima de 20. Aparte de eso, puedes crear el tuyo propio, pero será complicado.

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;
}

Lo anterior utiliza una repetición de cadenas fácil y barata ( (new Array(n+1)).join(str)). Podrías definir String.prototype.repeatusando la multiplicación campesina rusa y usarla en su lugar.

Esta respuesta sólo debe aplicarse al contexto de la pregunta: mostrar un número grande sin utilizar notación científica. Para cualquier otra cosa, debe utilizar una biblioteca BigInt , como BigNumber , Leemon's BigInt o BigInteger . En el futuro, el nuevo BigInt nativo (nota: no el de Leemon) debería estar disponible; Chromium y los navegadores basados ​​en él ( Chrome , el nuevo Edge [v79+], Brave ) y Firefox son compatibles; El soporte de Safari está en marcha.

Así es como usarías BigInt para ello:BigInt(n).toString()

Ejemplo:

Mostrar fragmento de código

Sin embargo, tenga en cuentaNumber.MAX_SAFE_INTEGER + 1 que cualquier número entero que genere como un número de JavaScript (no un BigInt) que tenga más de 15 o 16 dígitos (específicamente, mayor que [9,007,199,254,740,992]) puede redondearse, porque el tipo de número de JavaScript (IEEE-754 de doble precisión punto flotante) no puede contener con precisión todos los números enteros más allá de ese punto. A partir de Number.MAX_SAFE_INTEGER + 1que funciona en múltiplos de 2, ya no puede contener números impares (y de manera similar, en 18,014,398,509,481,984 comienza a funcionar en múltiplos de 4, luego 8, luego 16, ...).

En consecuencia, si puede confiar en BigIntel soporte, genere su número como una cadena que pase a la BigIntfunción:

const n = BigInt("YourNumberHere");

Ejemplo:

Mostrar fragmento de código

outis avatar Nov 06 '2009 07:11 outis

Sé que esta es una pregunta anterior, pero se muestra activa recientemente. MDN a LocaleString

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"

puede utilizar opciones para formatear la salida.

Nota:

Number.toLocaleString() redondea después de 16 decimales, de modo que...

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

...devoluciones...

586084736227728400000000000000000000000

Esto quizás no sea deseable si la precisión es importante en el resultado deseado.

flapjack17 avatar Jun 21 '2018 23:06 flapjack17