Czytania przez opisie ECMAScript 5.1 , +0
i-0
odznaczają.
Dlaczego więc +0 === -0
ocenia się true
?
javascript
Randomblue
źródło
źródło
Object.is
do rozróżnienia +0 i -0Odpowiedzi:
JavaScript używa standardu IEEE 754 do reprezentowania liczb. Z Wikipedii :
Artykuł zawiera dalsze informacje na temat różnych reprezentacji.
Więc to jest powód, dla którego technicznie należy rozróżnić oba zera.
To zachowanie jest wyraźnie zdefiniowane w sekcji 11.9.6 , Algorytm ścisłego porównywania równości (podkreślenie częściowo moje):
(To samo dotyczy przy
+0 == -0
okazji.)Wydaje się logiczne, aby traktować
+0
i-0
równorzędnie. W przeciwnym razie musielibyśmy wziąć to pod uwagę w naszym kodzie, a ja osobiście nie chcę tego robić;)Uwaga:
ES2015 wprowadza nową metodę porównania
Object.is
.Object.is
wyraźnie rozróżnia-0
i+0
:źródło
1/0 === Infinity; // true
i1/-0 === -Infinity; // true
.1 === 1
i+0 === -0
ale1/+0 !== 1/-0
. Jakie dziwne!+0 !== -0
;) To może naprawdę stwarzać problemy.0 !== +0
/0 !== -0
, co rzeczywiście stworzyłoby problemy!Dodam to jako odpowiedź, ponieważ przeoczyłem komentarz @ user113716.
Możesz sprawdzić -0, wykonując następujące czynności:
źródło
e±308
, że twoja liczba może być reprezentowana tylko w postaci zdenormalizowanej, a różne implementacje mają różne opinie na temat tego, gdzie je w ogóle wspierać, czy nie. Chodzi o to, że na niektórych maszynach w niektórych trybach zmiennoprzecinkowych twoja liczba jest reprezentowana jako,-0
a na innych jako zdenormalizowana liczba0.000000000000001e-308
. TakieWłaśnie natknąłem się na przykład, w którym +0 i -0 zachowują się rzeczywiście bardzo różnie:
Uważaj: nawet gdy używasz Math.round na liczbie ujemnej, takiej jak -0,0001, w rzeczywistości będzie to -0 i może zepsuć niektóre kolejne obliczenia, jak pokazano powyżej.
Szybkim i nieprzyjemnym sposobem rozwiązania tego problemu jest wykonanie czegoś takiego:
Lub tylko:
To konwertuje liczbę na +0 w przypadku, gdy było to -0.
źródło
W standardzie IEEE 754 używanym do reprezentowania typu Number w JavaScript znak jest reprezentowany przez bit (1 oznacza liczbę ujemną).
W rezultacie istnieje zarówno wartość ujemna, jak i dodatnia dla każdej możliwej do przedstawienia liczby, w tym
0
.Dlatego jedno
-0
i drugie+0
istnieje.źródło
Odpowiadając na oryginalny tytuł
Are +0 and -0 the same?
:brainslugs83
(w komentarzach odpowiedzi autorstwaSpudley
) wskazał na ważny przypadek, w którym +0 i -0 w JS to nie to samo - zaimplementowane jako funkcja:To, poza standardowym,
Math.sign
zwróci poprawny znak +0 i -0.źródło
Istnieją dwie możliwe wartości (reprezentacje bitów) dla 0. To nie jest unikalne. Może się to zdarzyć zwłaszcza w przypadku liczb zmiennoprzecinkowych. Dzieje się tak, ponieważ liczby zmiennoprzecinkowe są w rzeczywistości przechowywane jako rodzaj formuły.
Liczby całkowite można również przechowywać na różne sposoby. Możesz mieć wartość liczbową z dodatkowym bitem znaku, więc w 16-bitowej przestrzeni można przechowywać 15-bitową wartość całkowitą i bit znaku. W tej reprezentacji wartości 1000 (szesnastkowo) i 0000 to 0, ale jedna z nich to +0, a druga to -0.
Można tego uniknąć, odejmując 1 od wartości całkowitej, tak aby mieściła się w zakresie od -1 do -2 ^ 16, ale byłoby to niewygodne.
Bardziej powszechnym podejściem jest przechowywanie liczb całkowitych w „dwóch uzupełnieniach”, ale najwyraźniej ECMAscript zdecydował się tego nie robić. W tej metodzie numery mieszczą się w zakresie od 0000 do 7FFF dodatnich. Liczby ujemne zaczynają się od FFFF (-1) do 8000.
Oczywiście te same zasady dotyczą również większych liczb całkowitych, ale nie chcę, aby moje F się zużyło. ;)
źródło
+0 === -0
to trochę dziwne. Ponieważ teraz mamy1 === 1
i+0 === -0
ale1/+0 !== 1/-0
...+0 === -0
mimo że dwie reprezentacje bitów są różne.Możemy użyć
Object.is
do odróżnienia +0 i -0, i jeszcze jedno,NaN==NaN
.źródło
Zrzuciłbym to na metodę ścisłego porównania równości („===”). Spójrz na sekcję 4d
patrz 7.2.13 Ścisłe porównanie równości w specyfikacji
źródło
Wikipedia zawiera dobry artykuł wyjaśniający to zjawisko: http://en.wikipedia.org/wiki/Signed_zero
W skrócie, zarówno +0, jak i -0 są zdefiniowane w specyfikacjach zmiennoprzecinkowych IEEE. Oba są technicznie różne od 0 bez znaku, który jest liczbą całkowitą, ale w praktyce wszystkie dają zero, więc rozróżnienie można zignorować ze względów praktycznych.
źródło