Читая спецификацию ECMAScript 5.1 , +0
и -0
различаются.
Почему тогда +0 === -0
оценивать true
?
javascript
Randomblue
источник
источник
Object.is
чтобы различать +0 и -0Ответы:
JavaScript использует стандарт IEEE 754 для представления чисел. Из Википедии :
Статья содержит дополнительную информацию о различных представлениях.
Это и есть причина, по которой технически следует различать оба нуля.
Это поведение явно определено в разделе 11.9.6 , Алгоритм сравнения строгого равенства (выделение частично мое):
(То же самое относится и к
+0 == -0
кстати.)Вроде бы логично относиться
+0
и-0
как к равным. В противном случае мы должны были бы принять это во внимание в нашем коде, и я лично не хочу этого делать;)Примечание:
ES2015 вводит новый метод сравнения
Object.is
.Object.is
четко различает-0
и+0
:источник
1/0 === Infinity; // true
и есть1/-0 === -Infinity; // true
.1 === 1
и есть+0 === -0
но1/+0 !== 1/-0
. Как странно!+0 !== -0
;) Это может действительно создать проблемы.0 !== +0
/0 !== -0
, что тоже может создать проблемы!Я добавлю это как ответ, потому что я пропустил комментарий @ user113716.
Вы можете проверить на -0, выполнив это:
источник
e±308
, ваш номер может быть представлен только в денормализованной форме, и разные реализации имеют разные мнения о том, где их поддерживать или нет. Дело в том, что на некоторых машинах в некоторых режимах с плавающей запятой ваш номер представлен как,-0
а на других - как денормализованный номер0.000000000000001e-308
. Такие поплавки, так веселоЯ только что натолкнулся на пример, где +0 и -0 ведут себя совершенно по-разному:
Будьте осторожны: даже при использовании Math.round с отрицательным числом, таким как -0,0001, оно будет на самом деле -0 и может привести к некоторым последующим вычислениям, как показано выше.
Быстрый и грязный способ исправить это сделать что-то вроде:
или просто:
Это преобразует число в +0, если это было -0.
источник
В стандарте IEEE 754, используемом для представления типа Number в JavaScript, знак представлен битом (1 означает отрицательное число).
В результате существует как отрицательное, так и положительное значение для каждого представимого числа, в том числе
0
.Именно поэтому
-0
и+0
существуют.источник
Отвечая на оригинальное название
Are +0 and -0 the same?
:brainslugs83
(в комментариях ответа отSpudley
) указал на важный случай, когда +0 и -0 в JS не совпадают - реализованы как функция:Это, кроме стандартных,
Math.sign
вернет правильный знак +0 и -0.источник
Есть два возможных значения (битовые представления) для 0. Это не уникально. Особенно в числах с плавающей точкой это может произойти. Это потому, что числа с плавающей запятой на самом деле хранятся в виде формулы.
Целые числа также могут храниться разными способами. Вы можете иметь числовое значение с дополнительным битом знака, поэтому в 16-битном пространстве вы можете хранить 15-битное целочисленное значение и бит знака. В этом представлении значения 1000 (hex) и 0000 оба равны 0, но одно из них равно +0, а другое - -0.
Этого можно избежать, вычитая 1 из целочисленного значения, чтобы оно варьировалось от -1 до -2 ^ 16, но это было бы неудобно.
Более распространенный подход - хранить целые числа в «двух дополнениях», но, очевидно, ECMAscript предпочел не делать этого. В этом методе числа в диапазоне от 0000 до 7FFF положительны. Отрицательные числа начинаются с FFFF (-1) до 8000.
Конечно, те же правила применимы и к большим целым числам, но я не хочу, чтобы мой F изнашивался. ;)
источник
+0 === -0
это немного странным? Потому что теперь у нас есть1 === 1
и+0 === -0
но1/+0 !== 1/-0
...+0 === -0
несмотря на различие двухбитных представлений.Мы можем использовать ,
Object.is
чтобы различать +0 и -0, и еще одну вещь,NaN==NaN
.источник
Я бы свалил вину на метод сравнения строгого равенства ('==='). Посмотрите на раздел 4d
см. 7.2.13 Сравнение строгого равенства в спецификации
источник
В Википедии есть хорошая статья, чтобы объяснить это явление: http://en.wikipedia.org/wiki/Signed_zero
Вкратце, это и +0, и -0 определены в спецификациях IEEE с плавающей запятой. Они оба технически отличаются от 0 без знака, который является целым числом, но на практике все они оцениваются как ноль, поэтому различие можно игнорировать для всех практических целей.
источник