Lesen Sie die ECMAScript 5.1-Spezifikation durch +0
und -0
unterscheiden Sie sich.
Warum +0 === -0
bewertet dann true
?
javascript
Zufälliges Blau
quelle
quelle
Object.is
+0 und -0 unterscheiden könnenAntworten:
JavaScript verwendet den IEEE 754-Standard zur Darstellung von Zahlen. Aus Wikipedia :
Der Artikel enthält weitere Informationen zu den verschiedenen Darstellungen.
Dies ist der Grund, warum technisch gesehen beide Nullen unterschieden werden müssen.
Dieses Verhalten wird in Abschnitt 11.9.6 , dem Algorithmus für den Vergleich strikter Gleichheit (Betonung teilweise von mir), explizit definiert :
(Gleiches gilt
+0 == -0
übrigens.)Es scheint logisch
+0
und-0
gleich zu behandeln . Andernfalls müssten wir dies in unserem Code berücksichtigen und ich persönlich möchte das nicht tun;)Hinweis:
ES2015 führt eine neue Vergleichsmethode ein
Object.is
.Object.is
unterscheidet explizit zwischen-0
und+0
:quelle
1/0 === Infinity; // true
und1/-0 === -Infinity; // true
.1 === 1
und+0 === -0
aber1/+0 !== 1/-0
. Wie seltsam!+0 !== -0
;) Das könnte wirklich Probleme verursachen.0 !== +0
/0 !== -0
, was in der Tat auch Probleme verursachen würde!Ich werde dies als Antwort hinzufügen, da ich den Kommentar von @ user113716 übersehen habe.
Sie können dies auf -0 testen:
quelle
e±308
, dass Ihre Nummer nur in denormalisierter Form dargestellt werden kann und verschiedene Implementierungen unterschiedliche Meinungen darüber haben, wo sie überhaupt unterstützt werden sollen oder nicht. Der Punkt ist, dass auf einigen Maschinen in einigen Gleitkomma-Modi Ihre Nummer als-0
und auf anderen als denormalisierte Nummer dargestellt wird0.000000000000001e-308
. Solche Schwimmer, so lustigIch bin gerade auf ein Beispiel gestoßen, bei dem sich +0 und -0 tatsächlich sehr unterschiedlich verhalten:
Seien Sie vorsichtig: Selbst wenn Sie Math.round für eine negative Zahl wie -0.0001 verwenden, ist es tatsächlich -0 und kann einige nachfolgende Berechnungen wie oben gezeigt vermasseln.
Eine schnelle und schmutzige Möglichkeit, dies zu beheben, besteht darin, Folgendes zu tun:
oder nur:
Dies wandelt die Zahl in +0 um, falls sie -0 war.
quelle
In dem IEEE 754-Standard, der zur Darstellung des Zahlentyps in JavaScript verwendet wird, wird das Vorzeichen durch ein Bit dargestellt (eine 1 gibt eine negative Zahl an).
Infolgedessen gibt es sowohl einen negativen als auch einen positiven Wert für jede darstellbare Zahl, einschließlich
0
.Deshalb existieren beide
-0
und+0
.quelle
Beantwortung des Originaltitels
Are +0 and -0 the same?
:brainslugs83
(in Kommentaren der Antwort vonSpudley
) wies auf einen wichtigen Fall hin, in dem +0 und -0 in JS nicht gleich sind - implementiert als Funktion:Dies gibt anders als der Standard
Math.sign
das korrekte Vorzeichen von +0 und -0 zurück.quelle
Es gibt zwei mögliche Werte (Bitdarstellungen) für 0. Dies ist nicht eindeutig. Insbesondere bei Gleitkommazahlen kann dies auftreten. Das liegt daran, dass Gleitkommazahlen tatsächlich als eine Art Formel gespeichert werden.
Ganzzahlen können auch auf separate Weise gespeichert werden. Sie können einen numerischen Wert mit einem zusätzlichen Vorzeichenbit haben, sodass Sie in einem 16-Bit-Bereich einen 15-Bit-Ganzzahlwert und ein Vorzeichenbit speichern können. In dieser Darstellung sind der Wert 1000 (hex) und 0000 beide 0, aber einer von ihnen ist +0 und der andere ist -0.
Dies könnte vermieden werden, indem 1 vom ganzzahligen Wert subtrahiert wird, so dass er im Bereich von -1 bis -2 ^ 16 liegt. Dies wäre jedoch unpraktisch.
Ein üblicherer Ansatz besteht darin, Ganzzahlen in "zwei Ergänzungen" zu speichern, aber anscheinend hat ECMAscript entschieden, dies nicht zu tun. Bei dieser Methode reichen die Zahlen von 0000 bis 7FFF positiv. Negative Zahlen beginnen bei FFFF (-1) bis 8000.
Natürlich gelten die gleichen Regeln auch für größere Ganzzahlen, aber ich möchte nicht, dass sich mein F abnutzt. ;)
quelle
+0 === -0
ein bisschen komisch? Denn jetzt haben wir1 === 1
und+0 === -0
aber1/+0 !== 1/-0
...+0 === -0
obwohl die zwei Bit-Darstellungen unterschiedlich sind.Wir können
Object.is
+0 und -0 und noch etwas unterscheidenNaN==NaN
.quelle
Ich würde es der Methode des strengen Gleichheitsvergleichs ('===') zuschreiben. Schauen Sie sich Abschnitt 4d an
siehe 7.2.13 Strenger Gleichheitsvergleich zur Spezifikation
quelle
Wikipedia hat einen guten Artikel, um dieses Phänomen zu erklären: http://en.wikipedia.org/wiki/Signed_zero
Kurz gesagt, es sind sowohl +0 als auch -0 in den IEEE-Gleitkomma-Spezifikationen definiert. Beide unterscheiden sich technisch von 0 ohne Vorzeichen, was eine ganze Zahl ist. In der Praxis werden sie jedoch alle mit Null bewertet, sodass die Unterscheidung für alle praktischen Zwecke ignoriert werden kann.
quelle