Questo è definito dalla lingua? C'è un massimo definito? È diverso nei diversi browser?
1n << 10000n
è un numero intero veramente grande, senza perdere precisione, senza richiedere dipendenze (e inutile dirlo, nemmeno vicino a un limite).
Questo è definito dalla lingua? C'è un massimo definito? È diverso nei diversi browser?
1n << 10000n
è un numero intero veramente grande, senza perdere precisione, senza richiedere dipendenze (e inutile dirlo, nemmeno vicino a un limite).
Risposte:
JavaScript ha due tipi di numeri: Number
e BigInt
.
Il tipo di numero più frequentemente utilizzato Number
è un numero IEEE 754 a virgola mobile a 64 bit .
Il valore integrale esatto più grande di questo tipo è Number.MAX_SAFE_INTEGER
, che è:
Per dirla in prospettiva: un quadrilione di byte è un petabyte (o mille terabyte).
"Sicuro" in questo contesto si riferisce alla capacità di rappresentare esattamente i numeri interi e di confrontarli correttamente.
Si noti che tutti i numeri interi positivi e negativi la cui magnitudine non è maggiore di 2 53 sono rappresentabili nel
Number
tipo (in effetti, l'intero 0 ha due rappresentazioni, +0 e -0).
Per utilizzare in modo sicuro numeri interi più grandi di questo, è necessario utilizzare BigInt
, che non ha limite superiore.
Si noti che gli operatori bit a bit e gli operatori shift funzionano su numeri interi a 32 bit, quindi in questo caso, il numero intero massimo di sicurezza è 2 31 -1 o 2.147.483.647.
const log = console.log
var x = 9007199254740992
var y = -x
log(x == x + 1) // true !
log(y == y - 1) // also true !
// Arithmetic operators work, but bitwise/shifts only operate on int32:
log(x / 2) // 4503599627370496
log(x >> 1) // 0
log(x | 1) // 1
Nota tecnica sull'argomento del numero 9.007.199.254.740.992: esiste una rappresentazione IEEE-754 esatta di questo valore e puoi assegnare e leggere questo valore da una variabile, quindi per applicazioni scelte con molta attenzione nel dominio di numeri interi inferiori o uguali a questo valore, potresti considerarlo come un valore massimo.
Nel caso generale, è necessario considerare questo valore IEEE-754 come inesatto, perché è ambiguo se sta codificando il valore logico 9.007.199.254.740.992 o 9.007.199.254.740.993.
4294967295 === Math.pow(2,32) - 1;
> = ES6:
Number.MIN_SAFE_INTEGER;
Number.MAX_SAFE_INTEGER;
<= ES5
Dal riferimento :
Number.MAX_VALUE;
Number.MIN_VALUE;
Number.MIN_VALUE
è il numero positivo più piccolo possibile . Il valore minimo (ovvero inferiore a qualsiasi altra cosa) è probabilmente -Number.MAX_VALUE
.
Number.MIN_SAFE_INTEGER
eNumber.MAX_SAFE_INTEGER
È 2 53 == 9 007 199 254 740 992. Questo perché Number
s sono memorizzati come virgola mobile in una mantissa a 52 bit.
Il valore minimo è -2 53 .
Questo rende alcune cose divertenti accadendo
Math.pow(2, 53) == Math.pow(2, 53) + 1
>> true
E può anche essere pericoloso :)
var MAX_INT = Math.pow(2, 53); // 9 007 199 254 740 992
for (var i = MAX_INT; i < MAX_INT + 2; ++i) {
// infinite loop
}
Ulteriori letture: http://blog.vjeux.com/2010/javascript/javascript-max_int-number-limits.html
i += 1000000000
In JavaScript, c'è un numero chiamato Infinity
.
Esempi:
(Infinity>100)
=> true
// Also worth noting
Infinity - 1 == Infinity
=> true
Math.pow(2,1024) === Infinity
=> true
Questo può essere sufficiente per alcune domande su questo argomento.
min
variabile quando stai cercando un valore minimo.
Infinity - 1 === Infinity
1 - Infinity === -Infinity
La risposta di Jimmy rappresenta correttamente lo spettro intero JavaScript continuo compreso tra -9007199254740992 e 9007199254740992 inclusi (scusate 9007199254740993, potreste pensare di essere 9007199254740993, ma vi sbagliate! Dimostrazione sotto o in jsfiddle ).
console.log(9007199254740993);
Tuttavia, non esiste una risposta che lo trovi / dimostri in modo programmatico (diverso da quello di CoolAJ86 alluso nella sua risposta che sarebbe terminata in 28.56 anni;), quindi ecco un modo leggermente più efficiente per farlo (per essere precisi, è più efficiente di circa 28.559999999968312 anni :), insieme a un violino di prova :
/**
* Checks if adding/subtracting one to/from a number yields the correct result.
*
* @param number The number to test
* @return true if you can add/subtract 1, false otherwise.
*/
var canAddSubtractOneFromNumber = function(number) {
var numMinusOne = number - 1;
var numPlusOne = number + 1;
return ((number - numMinusOne) === 1) && ((number - numPlusOne) === -1);
}
//Find the highest number
var highestNumber = 3; //Start with an integer 1 or higher
//Get a number higher than the valid integer range
while (canAddSubtractOneFromNumber(highestNumber)) {
highestNumber *= 2;
}
//Find the lowest number you can't add/subtract 1 from
var numToSubtract = highestNumber / 4;
while (numToSubtract >= 1) {
while (!canAddSubtractOneFromNumber(highestNumber - numToSubtract)) {
highestNumber = highestNumber - numToSubtract;
}
numToSubtract /= 2;
}
//And there was much rejoicing. Yay.
console.log('HighestNumber = ' + highestNumber);
x++
ti dà il valore di x prima che si sia verificato l'incremento, quindi questo probabilmente spiega la discrepanza. Se vuoi che l'espressione valga la stessa cosa del valore finale di x, dovresti cambiarla in ++x
.
var MAX_INT = 4294967295;
Ho pensato di essere intelligente e trovare il valore con cui x + 1 === x
con un approccio più pragmatico.
La mia macchina può contare solo 10 milioni al secondo o giù di lì ... quindi rispedirò con la risposta definitiva tra 28,56 anni.
Se non puoi aspettare così a lungo, sono disposto a scommetterlo
9007199254740992 === Math.pow(2, 53) + 1
è abbastanza prova4294967295
ciò Math.pow(2,32) - 1
per evitare problemi previsti con lo spostamento dei bitAlla ricerca x + 1 === x
:
(function () {
"use strict";
var x = 0
, start = new Date().valueOf()
;
while (x + 1 != x) {
if (!(x % 10000000)) {
console.log(x);
}
x += 1
}
console.log(x, new Date().valueOf() - start);
}());
La risposta breve è "dipende".
Se si utilizzano operatori bit a bit ovunque (o se si fa riferimento alla lunghezza di un array), gli intervalli sono:
uNSIGNED: 0…(-1>>>0)
firmato: (-(-1>>>1)-1)…(-1>>>1)
(Succede che gli operatori bit a bit e la lunghezza massima di un array sono limitati a numeri interi a 32 bit.)
Se non si utilizzano operatori bit per bit o non si lavora con lunghezze di array:
firmato: (-Math.pow(2,53))…(+Math.pow(2,53))
Queste limitazioni sono imposte dalla rappresentazione interna del tipo "Numero", che generalmente corrisponde alla rappresentazione in virgola mobile a precisione doppia IEEE 754. (Si noti che a differenza dei numeri interi con segno tipici, l'entità del limite negativo è uguale all'entità del limite positivo, a causa delle caratteristiche della rappresentazione interna, che in realtà include uno 0 negativo !)
ECMAScript 6:
Number.MAX_SAFE_INTEGER = Math.pow(2, 53)-1;
Number.MIN_SAFE_INTEGER = -Number.MAX_SAFE_INTEGER;
MAX_SAFE_INTEGER
in tutti i browser lavorando all'indietro? Dovresti invece andare avanti? Vale a dire, Number.MAX_SAFE_INTEGER = 2 * (Math.pow (2, 52) - 1) + 1;
Math.pow(2, 53)-1
un'operazione sicura? Va uno più grande del più grande intero sicuro.
Molte risposte di epoche precedenti hanno mostrato il risultato true
di 9007199254740992 === 9007199254740992 + 1
verificare che 9 007 199 254 740 991 sia il numero intero massimo e sicuro.
E se continuiamo a fare accumulazione:
input: 9007199254740992 + 1 output: 9007199254740992 // expected: 9007199254740993
input: 9007199254740992 + 2 output: 9007199254740994 // expected: 9007199254740994
input: 9007199254740992 + 3 output: 9007199254740996 // expected: 9007199254740995
input: 9007199254740992 + 4 output: 9007199254740996 // expected: 9007199254740996
Potremmo scoprire che tra i numeri maggiori di 9 007 199 254 740 992 , sono rappresentabili solo i numeri pari .
È un'entrata per spiegare come funziona il formato binario a doppia precisione a 64 bit . Vediamo come 9 007 199 254 740 992 devono essere mantenuti (rappresentati) usando questo formato binario.
Utilizzando una breve versione per dimostrarlo da 4 503 599 627 370 496 :
1 . 0000 ---- 0000 * 2^52 => 1 0000 ---- 0000.
|-- 52 bits --| |exponent part| |-- 52 bits --|
Sul lato sinistro della freccia, abbiamo il valore di bit 1 e un punto radix adiacente , quindi moltiplicando 2^52
spostiamo a destra il punto radix di 52 passi e arriva alla fine. Ora otteniamo 4503599627370496 in binario.
Ora iniziamo ad accumulare 1 su questo valore fino a quando tutti i bit sono impostati su 1, che equivale a 9 007 199 254 740 991 in decimale.
1 . 0000 ---- 0000 * 2^52 => 1 0000 ---- 0000.
(+1)
1 . 0000 ---- 0001 * 2^52 => 1 0000 ---- 0001.
(+1)
1 . 0000 ---- 0010 * 2^52 => 1 0000 ---- 0010.
(+1)
.
.
.
1 . 1111 ---- 1111 * 2^52 => 1 1111 ---- 1111.
Ora, poiché in formato binario a 64 bit a doppia precisione , assegna rigorosamente 52 bit per frazione, non è più disponibile alcun bit da aggiungere per aggiungere un altro 1, quindi ciò che possiamo fare è riportare tutti i bit su 0, e manipolare la parte esponente:
|--> This bit is implicit and persistent.
|
1 . 1111 ---- 1111 * 2^52 => 1 1111 ---- 1111.
|-- 52 bits --| |-- 52 bits --|
(+1)
(radix point has no way to go)
1 . 0000 ---- 0000 * 2^52 * 2 => 1 0000 ---- 0000. * 2
|-- 52 bits --| |-- 52 bits --|
=> 1 . 0000 ---- 0000 * 2^53
|-- 52 bits --|
Ora otteniamo il 9 007 199 254 740 992 , e con il numero maggiore di esso, ciò che il formato potrebbe contenere è 2 volte della frazione , significa che ora ogni 1 aggiunta sulla parte della frazione equivale effettivamente a 2 aggiunte, ecco perché il doppio -precisione formato binario a 64 bit non può contenere numeri dispari quando il numero è maggiore di 9 007 199 254 740 992 :
(consume 2^52 to move radix point to the end)
1 . 0000 ---- 0001 * 2^53 => 1 0000 ---- 0001. * 2
|-- 52 bits --| |-- 52 bits --|
Quindi, quando il numero arriva a maggiore di 9 007 199254 740 992 * 2 = 18014398509 481 984, potrebbero essere mantenute solo 4 volte della frazione :
input: 18014398509481984 + 1 output: 18014398509481984 // expected: 18014398509481985
input: 18014398509481984 + 2 output: 18014398509481984 // expected: 18014398509481986
input: 18014398509481984 + 3 output: 18014398509481984 // expected: 18014398509481987
input: 18014398509481984 + 4 output: 18014398509481988 // expected: 18014398509481988
Che ne dici di un numero compreso tra [ 2 251 799 813 685 248 , 4 503 599 627 370 496 )?
1 . 0000 ---- 0001 * 2^51 => 1 0000 ---- 000.1
|-- 52 bits --| |-- 52 bits --|
Il valore di bit 1 dopo il punto di radice è esattamente 2 ^ -1. (= 1/2, = 0,5) Quindi quando il numero inferiore a 4 503 599 627 370 496 (2 ^ 52), è disponibile un bit per rappresentare le 1/2 volte dell'intero :
input: 4503599627370495.5 output: 4503599627370495.5
input: 4503599627370495.75 output: 4503599627370495.5
Meno di 2 251 799 813 685 248 (2 ^ 51)
input: 2251799813685246.75 output: 2251799813685246.8 // expected: 2251799813685246.75
input: 2251799813685246.25 output: 2251799813685246.2 // expected: 2251799813685246.25
input: 2251799813685246.5 output: 2251799813685246.5
// If the digits exceed 17, JavaScript round it to print it.
//, but the value is held correctly:
input: 2251799813685246.25.toString(2)
output: "111111111111111111111111111111111111111111111111110.01"
input: 2251799813685246.75.toString(2)
output: "111111111111111111111111111111111111111111111111110.11"
input: 2251799813685246.78.toString(2)
output: "111111111111111111111111111111111111111111111111110.11"
E qual è la gamma disponibile di parte esponente ? il formato assegna 11 bit per esso. Formato completo da Wiki : (Per maggiori dettagli, vai lì)
Quindi, per fare in modo che la parte esponente sia 2 ^ 52, dobbiamo esattamente impostare e = 1075.
Altri potrebbero aver già dato la risposta generica, ma ho pensato che sarebbe una buona idea dare un modo veloce per determinarla:
for (var x = 2; x + 1 !== x; x *= 2);
console.log(x);
Il che mi dà 9007199254740992 in meno di un millisecondo in Chrome 30.
Testerà i poteri di 2 per trovare quale, quando "aggiunto" 1, è uguale a se stesso.
Provare:
maxInt = -1 >>> 1
In Firefox 3.6 sono 2 ^ 31 - 1.
^
significa elevato al potere . Nella console javascript, ^
è XOR , non elevato a
101
e 2 è 010
. Ora, se li bitorali XOR, riceverai 5(101) ^ 2(010) = 7(111)
LEGGI QUESTO SE SEI CONFUSO Ciò che viene discusso qui Math.pow()
non è l' ^
operatore
Al momento della scrittura, Javascript sta ricevendo un nuovo tipo di dati: BigInt
. È una proposta TC39 nella fase 4 da includere in EcmaScript 2020 . BigInt
è disponibile in Chrome 67+, FireFox 68+, Opera 54 e Nodo 10.4.0. È in corso in Safari, et al ... Introduce letterali numerici con il suffisso "n" e consente una precisione arbitraria:
var a = 123456789012345678901012345678901n;
La precisione andrà comunque persa, ovviamente, quando un tale numero viene (forse involontariamente) costretto a un tipo di dati numerici.
E, ovviamente, ci saranno sempre limiti di precisione dovuti alla memoria finita e un costo in termini di tempo per allocare la memoria necessaria ed eseguire l'aritmetica su numeri così grandi.
Ad esempio, la generazione di un numero con centomila cifre decimali richiederà un notevole ritardo prima del completamento:
console.log(BigInt("1".padEnd(100000,"0")) + 1n)
... ma funziona.
Ho fatto un semplice test con una formula, X- (X + 1) = - 1, e il valore più grande di XI che può funzionare su Safari, Opera e Firefox (testato su OS X) è 9e15. Ecco il codice che ho usato per i test:
javascript: alert(9e15-(9e15+1));
9000000000000000
c'è 1 cifra significativa. in "9007199254740992" ci sono 15 cifre significative.
9000000000000000
com'è - ha 1
SF. dove 90*10^14
ha 2. ( sigfigscalculator.appspot.com ) & mathsfirst.massey.ac.nz/Algebra/Decimals/SigFig.htm (sezione in basso)
La
MAX_SAFE_INTEGER
costante ha un valore di9007199254740991
(9.007.199.254.740.991 o ~ 9 quadrilioni). Il ragionamento alla base di quel numero è che JavaScript utilizza numeri in formato a virgola mobile a precisione doppia come specificato in IEEE 754 e può rappresentare in modo sicuro solo numeri tra-(2^53 - 1)
e2^53 - 1
.Sicuro in questo contesto si riferisce alla capacità di rappresentare esattamente i numeri interi e di confrontarli correttamente. Ad esempio,
Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2
valuterà true, il che è matematicamente errato. Vedere Number.isSafeInteger () per ulteriori informazioni.Poiché
MAX_SAFE_INTEGER
è una proprietà statica di Number , la usi sempre comeNumber.MAX_SAFE_INTEGER
, anziché come proprietà di un oggetto Number che hai creato.
Nel javascript incorporato di Google Chrome, puoi andare a circa 2 ^ 1024 prima che il numero si chiami infinito.
In JavaScript la rappresentazione dei numeri è 2^53 - 1
.
Scato scrive:
tutto ciò che si desidera utilizzare per operazioni bit a bit deve essere compreso tra 0x80000000 (-2147483648 o -2 ^ 31) e 0x7fffffff (2147483647 o 2 ^ 31 - 1).
la console ti dirà che 0x80000000 è uguale a +2147483648, ma 0x80000000 e 0x80000000 è uguale a -2147483648
I decimali esadecimali sono valori positivi senza segno, quindi 0x80000000 = 2147483648 - questo è matematicamente corretto. Se vuoi renderlo un valore con segno devi spostare a destra: 0x80000000 >> 0 = -2147483648. Puoi anche scrivere 1 << 31.
Firefox 3 non sembra avere problemi con numeri enormi.
1e + 200 * 1e + 100 calcolerà la multa fino a 1e + 300.
Anche Safari sembra non avere problemi. (Per la cronaca, questo è su un Mac se qualcun altro decide di testarlo.)
A meno che non abbia perso la testa in questo momento della giornata, questo è molto più grande di un intero a 64 bit.
100000000000000010 - 1 => 100000000000000020
Node.js e Google Chrome sembrano entrambi utilizzare valori in virgola mobile a 1024 bit, quindi:
Number.MAX_VALUE = 1.7976931348623157e+308
2^53
viene chiamato MAX_SAFE_INT
perché sopra quel punto i valori diventano approssimazioni, allo stesso modo delle frazioni.