Domanda

Perché è q == 0 nella seguente script?

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

Vorrei che il risultato dovrebbe essere 10. Qual è il modo corretto di sottrarre questi due numeri?

È stato utile?

Soluzione

Poiché i numeri in JavaScript sono galleggianti-point. Essi hanno limitato la precisione.

Quando JavaScript vede una lunghissima serie, si arrotonda al numero più vicino si può rappresentare come un float a 64 bit. Nello script, start e end ottenere arrotondato allo stesso valore.

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

Non c'è modo integrato a fare l'aritmetica preciso su grandi numeri interi, ma è possibile utilizzare una libreria BigInteger come questo .

Altri suggerimenti

Jason già pubblicato il perché. Per una soluzione, è possibile ottenere una libreria JavaScript BigInt a 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+/, ''))


Meglio usare biblioteca big-intero per queste cose, in modo da gestire tutti i diversi casi di test.

Questa è solo per il un caso generale è possibile utilizzare ....

Si è spiegato nel JavaScript documentazione :

  

Secondo lo standard ECMAScript, c'è solo un tipo di numero: doppia precisione 64- bit formato binario IEEE 754 valore (numeri tra -(2 53 -1) e 2 53 -1). Non v'è alcun tipo specifico per gli interi.

Pagina

formato in virgola mobile a doppia precisione spiega:

  

Tra 2 52 = 4,503,599,627,370,496 e 2 53 = 9,007,199,254,740,992 i numeri rappresentabili sono esattamente i numeri interi. Per la gamma successiva, da 2 53 per 2 54 , tutto è moltiplicato per 2, in modo che i numeri rappresentabili sono quelli pari, ecc.

(Tutti i numeri interi più piccoli di 2 52 sono rappresentati esattamente.)

1234567890123456789 e 1234567890123456799 sono più grandi di 2 60 = 1152921504606846976. A tale portata solo circa 1% dei numeri interi sono memorizzati esattamente con doppia precisione formato in virgola mobile.

Questi due non possono essere immagazzinate esattamente. Entrambi sono arrotondati a 1234567890123456800.


Il JavaScript documentazione anche spiegato come dire se un numero un numero intero viene memorizzato esattamente:

  

[...] e partendo da ECMAScript 6, si è anche in grado di verificare se un numero è in doppia precisione in virgola mobile intervallo di numeri utilizzando Number.isSafeInteger() così come Number.MAX_SAFE_INTEGER e Number.MIN_SAFE_INTEGER . Al di là di questa gamma, numeri interi in JavaScript non sono più sicuri e sarà un punto di approssimazione doppia precisione floating del valore.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top