Isso é definido pelo idioma? Existe um máximo definido? É diferente em navegadores diferentes?
1n << 10000n
é um número inteiro realmente grande, sem perder precisão, sem exigir dependências (e nem é preciso dizer, nem mesmo perto de um limite).
Isso é definido pelo idioma? Existe um máximo definido? É diferente em navegadores diferentes?
1n << 10000n
é um número inteiro realmente grande, sem perder precisão, sem exigir dependências (e nem é preciso dizer, nem mesmo perto de um limite).
Respostas:
JavaScript tem dois tipos de números: Number
e BigInt
.
O tipo de número usado com mais frequência,, Number
é um número IEEE 754 de ponto flutuante de 64 bits .
O maior valor integral exato desse tipo Number.MAX_SAFE_INTEGER
é:
Para colocar isso em perspectiva: um quatrilhão de bytes é um petabyte (ou mil terabytes).
"Seguro" neste contexto refere-se à capacidade de representar números inteiros exatamente e compará-los corretamente.
Observe que todos os números inteiros positivos e negativos cuja magnitude não é maior que 2 53 são representáveis no
Number
tipo (de fato, o número 0 tem duas representações, +0 e -0).
Para usar com segurança números inteiros maiores que isso, você precisa usar BigInt
, que não tem limite superior.
Observe que os operadores bit a bit e shift operam em números inteiros de 32 bits; portanto, nesse caso, o número máximo máximo de segurança é 2 31 -1 ou 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 técnica sobre o assunto do número 9.007.199.254.740.992: Há uma representação exata do IEEE-754 desse valor, e você pode atribuir e ler esse valor de uma variável, portanto, com muito cuidado aplicativos escolhidos no domínio de números inteiros menores ou iguais a esse valor, você pode tratar isso como um valor máximo.
No caso geral, você deve tratar esse valor IEEE-754 como inexato, porque é ambíguo se ele está codificando o valor lógico 9.007.199.254.740.992 ou 9.007.199.254.740.993.
4294967295 === Math.pow(2,32) - 1;
> = ES6:
Number.MIN_SAFE_INTEGER;
Number.MAX_SAFE_INTEGER;
<= ES5
A partir da referência :
Number.MAX_VALUE;
Number.MIN_VALUE;
Number.MIN_VALUE
é o menor número positivo possível . O menor valor (ou seja, menor que qualquer outra coisa) é provavelmente -Number.MAX_VALUE
.
Number.MIN_SAFE_INTEGER
eNumber.MAX_SAFE_INTEGER
É 2 53 == 9 007 199 254 740 992. Isso ocorre porque Number
s são armazenados como ponto flutuante em uma mantissa de 52 bits.
O valor mínimo é -2 53 .
Isso faz algumas coisas divertidas acontecerem
Math.pow(2, 53) == Math.pow(2, 53) + 1
>> true
E também pode ser perigoso :)
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
}
Outras leituras: http://blog.vjeux.com/2010/javascript/javascript-max_int-number-limits.html
i += 1000000000
Em JavaScript, há um número chamado Infinity
.
Exemplos:
(Infinity>100)
=> true
// Also worth noting
Infinity - 1 == Infinity
=> true
Math.pow(2,1024) === Infinity
=> true
Isso pode ser suficiente para algumas perguntas sobre este tópico.
min
variável quando você procura um valor mínimo.
Infinity - 1 === Infinity
1 - Infinity === -Infinity
A resposta de Jimmy representa corretamente o espectro inteiro contínuo do JavaScript como -9007199254740992 a 9007199254740992 inclusive (desculpe 9007199254740993, você pode pensar que é 9007199254740993, mas está errado! Demonstração abaixo ou em jsfiddle ).
console.log(9007199254740993);
No entanto, não há resposta que encontre / prove isso programaticamente (além da mencionada por CoolAJ86 em sua resposta que terminaria em 28,56 anos;), então aqui está uma maneira um pouco mais eficiente de fazer isso (para ser preciso, é mais eficiente por cerca de 28,559999999968312 anos :), juntamente com um violino de teste :
/**
* 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++
fornece o valor de x antes que o incremento ocorra, o que provavelmente explica a discrepância. Se você deseja que a expressão seja avaliada da mesma forma que o valor final de x, altere-a para ++x
.
var MAX_INT = 4294967295;
Eu pensei que seria inteligente e encontraria o valor pelo qual x + 1 === x
com uma abordagem mais pragmática.
Minha máquina pode contar apenas 10 milhões por segundo, mais ou menos ... então postarei de volta com a resposta definitiva em 28,56 anos.
Se você não pode esperar tanto, estou disposto a apostar que
9007199254740992 === Math.pow(2, 53) + 1
é prova suficiente4294967295
que é Math.pow(2,32) - 1
para evitar problemas esperados com a mudança de bitsEncontrando 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);
}());
A resposta curta é "depende".
Se você estiver usando operadores bit a bit em qualquer lugar (ou se estiver se referindo ao comprimento de uma matriz), os intervalos serão:
Não assinado: 0…(-1>>>0)
Assinado: (-(-1>>>1)-1)…(-1>>>1)
(Ocorre que os operadores bit a bit e o comprimento máximo de uma matriz são restritos a números inteiros de 32 bits.)
Se você não estiver usando operadores bit a bit ou trabalhando com comprimentos de matriz:
Assinado: (-Math.pow(2,53))…(+Math.pow(2,53))
Essas limitações são impostas pela representação interna do tipo “Número”, que geralmente corresponde à representação de ponto flutuante de precisão dupla IEEE 754. (Observe que, diferentemente dos números inteiros assinados típicos, a magnitude do limite negativo é a mesma que a magnitude do limite positivo, devido às características da representação interna, que na verdade inclui um 0 negativo !)
ECMAScript 6:
Number.MAX_SAFE_INTEGER = Math.pow(2, 53)-1;
Number.MIN_SAFE_INTEGER = -Number.MAX_SAFE_INTEGER;
MAX_SAFE_INTEGER
em todos os navegadores trabalhando de trás para frente? Em vez disso, você deve avançar? Ou seja, Number.MAX_SAFE_INTEGER = 2 * (Math.pow (2, 52) - 1) + 1;
Math.pow(2, 53)-1
uma operação segura? Vai um número maior que o maior número inteiro seguro.
Muitas respostas de épocas anteriores mostraram o resultado true
de 9007199254740992 === 9007199254740992 + 1
verificar se 9 007 199 254 740 991 é o número máximo e seguro.
E se continuarmos fazendo acumulação:
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
Pudemos descobrir que, entre números maiores que 9 007 199 254 740 992 , apenas números pares são representáveis .
É uma entrada para explicar como o formato binário de 64 bits de precisão dupla funciona nisso. Vamos ver como 9 007 199 254 740 992 são mantidos (representados) usando este formato binário.
Usando uma versão resumida para demonstrá-la em 4 503 599 627 370 496 :
1 . 0000 ---- 0000 * 2^52 => 1 0000 ---- 0000.
|-- 52 bits --| |exponent part| |-- 52 bits --|
No lado esquerdo da seta, temos o valor de bit 1 e um ponto de raiz adjacente ; então, multiplicando 2^52
, movemos à direita o ponto de raiz 52 passos, e ele vai até o fim. Agora temos 4503599627370496 em binário.
Agora começamos a acumular 1 para esse valor até que todos os bits sejam definidos como 1, o que equivale a 9 007 199 254 740 991 em decimal.
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.
Agora, como no formato binário de 64 bits de precisão dupla , ele distribui estritamente 52 bits por fração, não há mais bits disponíveis para adicionar mais 1, então o que podemos fazer é definir todos os bits de volta para 0 e manipular a parte do expoente:
|--> 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 --|
Agora, obtemos 9 007 199 254 740 992 e, com o número maior, o que o formato pode conter são 2 vezes a fração , significa que agora cada 1 adição na parte da fração é realmente igual a 2, é por isso que o dobro formato binário de 64 bits de precisão não pode conter números ímpares quando o número for maior que 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 --|
Portanto, quando o número chegar a mais de 9 007 199 254 740 992 * 2 = 18 014 398 509 481 984, apenas 4 vezes da fração poderiam ser mantidas:
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
Que tal um número entre [ 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 --|
O valor do bit 1 após o ponto radix é 2 ^ -1 exatamente. (= 1/2, = 0,5) Portanto, quando o número for menor que 4 503 599 627 370 496 (2 ^ 52), há um bit disponível para representar as 1/2 vezes do número inteiro :
input: 4503599627370495.5 output: 4503599627370495.5
input: 4503599627370495.75 output: 4503599627370495.5
Menos de 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 é o intervalo disponível da parte do expoente ? o formato aloca 11 bits para ele. Formato completo do Wiki : (Para mais detalhes, visite o site)
Portanto, para fazer a parte do expoente ser 2 ^ 52, precisamos exatamente definir e = 1075.
Outros já podem ter dado a resposta genérica, mas pensei que seria uma boa idéia fornecer uma maneira rápida de determiná-la:
for (var x = 2; x + 1 !== x; x *= 2);
console.log(x);
O que me dá 9007199254740992 em menos de um milissegundo no Chrome 30.
Ele testará poderes de 2 para descobrir qual deles, quando 'adicionado' 1, é igual a si mesmo.
Tentar:
maxInt = -1 >>> 1
No Firefox 3.6, é 2 ^ 31 - 1.
^
meios elevados ao poder . No console javascript, ^
é XOR , não levantou-to
101
e 2 é 010
. Agora, se você XOR-los, você vai ter 5(101) ^ 2(010) = 7(111)
LEIA ESTE Se você está confuso O que está sendo discutido aqui é Math.pow()
não o ^
operador
No momento da escrita, JavaScript está recebendo um novo tipo de dados: BigInt
. É uma proposta do TC39 no estágio 4 a ser incluída no EcmaScript 2020 . BigInt
está disponível no Chrome 67+, FireFox 68+, Opera 54 e Node 10.4.0. Está em andamento no Safari, etc. Ele introduz literais numéricos com o sufixo "n" e permite precisão arbitrária:
var a = 123456789012345678901012345678901n;
A precisão ainda será perdida, é claro, quando esse número for (talvez não intencionalmente) coagido a um tipo de dados numérico.
E, obviamente, sempre haverá limitações de precisão devido à memória finita e um custo em termos de tempo para alocar a memória necessária e executar aritmética em números tão grandes.
Por exemplo, a geração de um número com cem mil dígitos decimais levará um atraso notável antes da conclusão:
console.log(BigInt("1".padEnd(100000,"0")) + 1n)
... mas funciona.
Fiz um teste simples com uma fórmula, X- (X + 1) = - 1, e o maior valor de XI pode funcionar no Safari, Opera e Firefox (testado no OS X) é 9e15. Aqui está o código que eu usei para testar:
javascript: alert(9e15-(9e15+1));
9000000000000000
Existe um número significativo. em 9007199254740992, existem 15 números significativos.
9000000000000000
como é - tem 1
SF. onde 90*10^14
tem 2. ( sigfigscalculator.appspot.com ) & mathsfirst.massey.ac.nz/Algebra/Decimals/SigFig.htm (seção inferior)
A
MAX_SAFE_INTEGER
constante tem um valor de9007199254740991
(9.007.199.254.740.991 ou ~ 9 quadrilhões). O raciocínio por trás desse número é que o JavaScript usa números de formato de ponto flutuante de precisão dupla, conforme especificado no IEEE 754 e pode representar apenas números com segurança entre-(2^53 - 1)
e2^53 - 1
.Seguro neste contexto refere-se à capacidade de representar números inteiros exatamente e compará-los corretamente. Por exemplo,
Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2
avaliará como verdadeiro, que é matematicamente incorreto. Consulte Number.isSafeInteger () para obter mais informações.Como
MAX_SAFE_INTEGER
é uma propriedade estática de Number , você sempre a usa comoNumber.MAX_SAFE_INTEGER
, e não como uma propriedade de um objeto Number que você criou.
No javascript interno do Google Chrome, você pode ir para aproximadamente 2 ^ 1024 antes que o número seja chamado infinito.
Em JavaScript, a representação dos números é 2^53 - 1
.
Scato escreve:
qualquer coisa que você queira usar para operações bit a bit deve estar entre 0x80000000 (-2147483648 ou -2 ^ 31) e 0x7fffffff (2147483647 ou 2 ^ 31 - 1).
o console informará que 0x80000000 é igual a +2147483648, mas 0x80000000 e 0x80000000 é igual a -2147483648
Os decimais hexadecimais são valores positivos não assinados, portanto, 0x80000000 = 2147483648 - isso é matematicamente correto. Se você deseja transformá-lo em um valor assinado, precisa mudar à direita: 0x80000000 >> 0 = -2147483648. Você também pode escrever 1 << 31.
O Firefox 3 parece não ter problemas com grandes números.
1e + 200 * 1e + 100 calculará multa para 1e + 300.
O Safari parece não ter problemas com isso também. (Para constar, este é um Mac se alguém decidir testá-lo.)
A menos que eu tenha perdido o cérebro a essa hora do dia, isso é muito maior que um número inteiro de 64 bits.
100000000000000010 - 1 => 100000000000000020
O Node.js e o Google Chrome parecem estar usando valores de ponto flutuante de 1024 bits, portanto:
Number.MAX_VALUE = 1.7976931348623157e+308
2^53
é chamado MAX_SAFE_INT
porque, acima desse ponto, os valores se tornam aproximações, da mesma forma que as frações.