Pregunta

¿Por qué es q == 0 en la siguiente secuencia de comandos?

<script>
  var start = 1234567890123456789;
  var end =   1234567890123456799;
  var q = end - start;
  alert(q);
</script>

Me gustaría que el resultado debería ser 10. ¿Cuál es la forma correcta de restar estos dos números?

¿Fue útil?

Solución

Debido a que los números en JavaScript se coma flotante. Han una precisión limitada.

Cuando JavaScript ve un número muy largo, se redondea al número más cercano se puede representar como un flotador de 64 bits. En su guión, y start end se redondean a un mismo valor.

alert(1234567890123456789);   // says: 1234567890123456800
alert(1234567890123456799);   // says: 1234567890123456800

No hay manera integrada para realizar operaciones aritméticas precisa en grandes números enteros, pero se puede utilizar una biblioteca BigInteger como éste .

Otros consejos

Jason ya se registró el por qué. Para una solución, se puede obtener una biblioteca de Javascript Bigint en http: // www- cs-students.stanford.edu/~tjw/jsbn/

const subtract = (a, b) => [a, b].map(n => [...n].reverse()).reduce((a, b) => a.reduce((r, d, i) => {
    let s = d - (b[i] || 0)
    if (s < 0) {
        s += 10
        a[i + 1]--
    }
    return '' + s + r
}, '').replace(/^0+/, ''))


un mejor uso de la biblioteca de gran número entero de estas cosas con el fin de manejar todos los casos de prueba diferentes.

Esto es sólo para el caso general se puede usar ....

Se explica en el JavaScript documentación :

  

De acuerdo con el estándar ECMAScript, sólo hay un tipo de número: de precisión doble 64- formato binario bit IEEE 754 valor (números entre -(2 53 -1) y 2 53 -1). No existe un tipo específico de números enteros.

página

formato de coma flotante de doble precisión explica:

  

Entre 2 52 = 4,503,599,627,370,496 y 2 53 = 9,007,199,254,740,992 los números representables son exactamente los números enteros. Para el siguiente rango, desde 2 53 a 2 54 , todo se multiplica por 2, así que los números representables son las pares, etc.

(Todos los números enteros más pequeños que 2 52 se representan con exactitud.)

1234567890123456789 y 1234567890123456799 son más grandes que 2 60 = 1152921504606846976. En esta magnitud sólo alrededor del 1% de los números enteros se almacenan utilizando exactamente el doble precisión formato de coma flotante.

Estos dos no se pueden almacenar exactamente. Ambos se redondean a 1234567890123456800.


El JavaScript documentación también se explica cómo saber si un número de un entero se almacena exactamente:

  

[...] y comenzando con ECMAScript 6, que también son capaces de comprobar si un número está en la doble precisión en coma flotante rango de números usando Number.isSafeInteger() , así como Number.MAX_SAFE_INTEGER y Number.MIN_SAFE_INTEGER . Más allá de este rango, los enteros de JavaScript no son seguros más y serán una aproximación punto flotante de doble precisión del valor.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top