通过阅读的ECMAScript 5.1规范,+0
和-0
被区分。
那为什么要+0 === -0
评估true
?
Object.is
用来区分+0和-0
通过阅读的ECMAScript 5.1规范,+0
和-0
被区分。
那为什么要+0 === -0
评估true
?
Object.is
用来区分+0和-0
Answers:
JavaScript使用IEEE 754标准表示数字。从维基百科:
有符号的零为零,具有相关的符号。在普通算术中,−0 = +0 =0。但是,在计算中,某些数字表示形式允许存在两个零,通常用-0(负零)和+0(正零)表示。这在某些带符号的整数表示形式以及大多数浮点数表示形式中都会发生。数字0通常被编码为+0,但是可以用+0或-0表示。
IEEE 754浮点算术标准(目前大多数支持浮点数的计算机和编程语言都在使用)要求+0和-0。零可被视为扩展实数线的变体,因此1 / −0 =-∞和1 / + 0 = +∞,仅对于±0 /±0和±∞/±∞未定义以零除。
本文包含有关不同表示形式的更多信息。
因此,这就是为什么在技术上必须区分两个零的原因。
但是,
+0 === -0
计算结果为true。这是为什么 (...) ?
此行为已在第11.9.6节 “ 严格平等比较算法”中明确定义(部分强调我的行为):
比较
x === y
,其中x
和y
是值,产生true或false。这样的比较执行如下:(...)
如果Type(x)是Number,则
- 如果x为NaN,则返回false。
- 如果y为NaN,则返回false。
- 如果x与y相同,则返回true。
- 如果x为+ 0,y为−0,则返回true。
- 如果x为−0,y为+0,则返回true。
- 返回false。
(...)
(+0 == -0
顺便说一句。)
从逻辑上看+0
,-0
应平等对待。否则,我们将不得不在我们的代码中考虑到这一点,而我个人不想这样做;)
注意:
ES2015引入了一种新的比较方法Object.is
。Object.is
明确区分-0
和+0
:
Object.is(-0, +0); // false
1/0 === Infinity; // true
和1/-0 === -Infinity; // true
。
1 === 1
and +0 === -0
但是1/+0 !== 1/-0
。真奇怪
+0 !== -0
;)更好,这确实可能会造成问题。
0 !== +0
/ 0 !== -0
,这确实也会造成问题!
我将其添加为答案,因为我忽略了@ user113716的评论。
您可以通过执行以下操作测试-0:
function isMinusZero(value) {
return 1/value === -Infinity;
}
isMinusZero(0); // false
isMinusZero(-0); // true
e±308
,您的数字只能以非规范化形式表示,并且不同的实现对在何处支持它们完全不支持。关键是,在某些机器上,在某些浮点模式下,您的数字表示为,-0
而在其他机器上则以非规范化的数字表示0.000000000000001e-308
。这样的漂浮物,如此有趣
我刚刚遇到了一个示例,其中+0和-0的行为确实有很大不同:
Math.atan2(0, 0); //returns 0
Math.atan2(0, -0); //returns Pi
请注意:即使对-0.0001之类的负数使用Math.round时,它实际上也将为-0,并且可能会破坏如上所示的一些后续计算。
解决此问题的快速而肮脏的方法是做类似的事情:
if (x==0) x=0;
要不就:
x+=0;
如果是-0,则将数字转换为+0。
在用于表示JavaScript中Number类型的IEEE 754标准中,符号用一位表示(a 1表示负数)。
结果,每个可表示的数字(包括)同时存在一个负值和一个正值0
。
这就是为什么两者-0
同时+0
存在。
0有两个可能的值(位表示)。这不是唯一的。特别是在浮点数中,可能会发生这种情况。那是因为浮点数实际上是作为一种公式存储的。
整数也可以单独存储。您可以使用带有附加符号位的数字值,因此在16位空间中,可以存储15位整数值和符号位。在此表示形式中,值1000(十六进制)和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
尽管两个位表示形式不同,您也无法解释为什么。
维基百科上有一篇很好的文章来解释这种现象:http : //en.wikipedia.org/wiki/Signed_zero
简而言之,它的+0和-0都在IEEE浮点规范中定义。从技术上讲,它们在没有符号的情况下都与0区别,整数是零,但实际上它们都为零,因此,出于所有实际目的,该区别可以忽略。