A leitura através da especificação ECMAScript 5,1 , +0
e -0
são distinguidos.
Por que, então, +0 === -0
avalia a true
?
javascript
Randomblue
fonte
fonte
Object.is
para distinguir +0 e -0Respostas:
JavaScript usa o padrão IEEE 754 para representar números. Da Wikipedia :
O artigo contém mais informações sobre as diferentes representações.
Portanto, essa é a razão pela qual, tecnicamente, os dois zeros devem ser distinguidos.
Esse comportamento é definido explicitamente na seção 11.9.6 , o Algoritmo de comparação estrita de igualdade (ênfase parcialmente minha):
(O mesmo vale para
+0 == -0
btw.)Parece logicamente tratar
+0
e-0
igual. Caso contrário, teríamos que levar isso em conta em nosso código e eu, pessoalmente, não quero fazer isso;)Nota:
O ES2015 apresenta um novo método de comparação
Object.is
,.Object.is
distingue explicitamente entre-0
e+0
:fonte
1/0 === Infinity; // true
e1/-0 === -Infinity; // true
.1 === 1
e+0 === -0
mas1/+0 !== 1/-0
. Que estranho!+0 !== -0
;) Isso pode realmente criar problemas.0 !== +0
/0 !== -0
, o que também criaria problemas também!Acrescentarei isso como resposta, porque ignorei o comentário de @ user113716.
Você pode testar -0 fazendo o seguinte:
fonte
e±308
seu número pode ser representado apenas na forma desnormalizada e diferentes implementações têm opiniões diferentes sobre onde apoiá-los ou não. O ponto é que, em algumas máquinas, em alguns modos de ponto flutuante, seu número é representado como-0
em outras, como número desnormalizado0.000000000000001e-308
. Esses carros alegóricos, tão divertidoAcabei de encontrar um exemplo em que +0 e -0 se comportam de maneira muito diferente:
Cuidado: mesmo ao usar Math.round em um número negativo como -0.0001, ele será realmente -0 e poderá estragar alguns cálculos subsequentes, como mostrado acima.
A maneira rápida e suja de corrigir isso é fazer algo como:
ou apenas:
Isso converte o número em +0, caso seja -0.
fonte
No padrão IEEE 754 usado para representar o tipo Number em JavaScript, o sinal é representado por um bit (1 indica um número negativo).
Como resultado, existe um valor negativo e um positivo para cada número representável, inclusive
0
.É por isso que ambos
-0
e+0
existem.fonte
Respondendo ao título original
Are +0 and -0 the same?
:brainslugs83
(nos comentários da resposta deSpudley
) apontou um caso importante em que +0 e -0 em JS não são os mesmos - implementados como função:Isso, além do padrão,
Math.sign
retornará o sinal correto de +0 e -0.fonte
Existem dois valores possíveis (representações de bits) para 0. Isso não é exclusivo. Especialmente em números de ponto flutuante, isso pode ocorrer. Isso ocorre porque os números de ponto flutuante são realmente armazenados como um tipo de fórmula.
Os números inteiros também podem ser armazenados de maneiras separadas. Você pode ter um valor numérico com um bit de sinal adicional; portanto, em um espaço de 16 bits, você pode armazenar um valor inteiro de 15 bits e um bit de sinal. Nesta representação, o valor 1000 (hex) e 0000 são 0, mas um deles é +0 e o outro é -0.
Isso poderia ser evitado subtraindo 1 do valor inteiro, variando de -1 a -2 ^ 16, mas isso seria inconveniente.
Uma abordagem mais comum é armazenar números inteiros em 'dois complementos', mas aparentemente o ECMAscript optou por não. Neste método, os números variam de 0000 a 7FFF positivo. Os números negativos começam em FFFF (-1) a 8000.
Obviamente, as mesmas regras também se aplicam a números inteiros maiores, mas não quero que meu F se esgote. ;)
fonte
+0 === -0
um pouco estranho. Porque agora nós temos1 === 1
e+0 === -0
mas1/+0 !== 1/-0
...+0 === -0
apesar das representações de dois bits serem diferentes.Podemos usar
Object.is
para distinguir +0 e -0 e mais uma coisaNaN==NaN
,.fonte
Eu culparia o método de comparação estrita da igualdade ('==='). Veja a seção 4d
consulte 7.2.13 Comparação estrita de igualdade na especificação
fonte
A Wikipedia tem um bom artigo para explicar esse fenômeno: http://en.wikipedia.org/wiki/Signed_zero
Em resumo, ambos +0 e -0 são definidos nas especificações de ponto flutuante IEEE. Ambos são tecnicamente distintos de 0 sem um sinal, que é um número inteiro, mas, na prática, todos são avaliados como zero, de modo que a distinção pode ser ignorada para todos os fins práticos.
fonte