+ 0和-0是一样的吗?

通过阅读ECMAScript 5.1规范 , +0-0是有区别的。

为什么然后+0 === -0评估为true

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节 严格平等比较algorithm (部分强调我的)中明确定义:

比较x === y ,其中xy是值,产生truefalse 。 这样的比较如下进行:

(……)

  • 如果Type(x)是Number,那么

    1. 如果x是NaN,则返回false。
    2. 如果y是NaN,则返回false。
    3. 如果x与y的Number值相同,则返回true。
    4. 如果x是+0,y是-0,则返回true。
    5. 如果x是-0,y是+0,则返回true。
    6. 返回false。

(……)

(这同样适用于+0 == -0 btw。)

从逻辑上来看, +0-0是相等的。 否则,我们将不得不在我们的代码中考虑到这一点,我个人不希望这样做;)


注意:

ES2015引入了一种新的比较方法Object.isObject.is明确区分-0+0

 Object.is(-0, +0); // false 

我会添加这个答案,因为我忽略了@ user113716的评论。

你可以通过这样来testing-0:

 function isMinusZero(value) { return 1/value === -Infinity; } isMinusZero(0); // false isMinusZero(-0); // true 

有两个可能的值(比特表示)为0.这不是唯一的。 尤其是在浮点数字中,这可能会发生。 这是因为浮点数实际上是作为一种公式存储的。

整数也可以单独存储。 您可以使用附加的符号位来表示数值,因此在16位空间中,可以存储15位整数值和符号位。 在这种表示中,值1000(hex)和0000都是0,但其中一个是+0,另一个是-0。

这可以通过从整数值中减去1来避免,所以它的范围是从-1到-2 ^ 16,但这样做会很不方便。

更常见的方法是将整数存储在“两个补码”中,但显然ECMAscriptselect不这样做。 在这个方法中,数字范围从0000到7FFF为正数。 负数从FFFF(-1)开始到8000。

当然,同样的规则也适用于较大的整数,但我不希望我的F磨损。 ;)

在用于表示JavaScript中的Numbertypes的IEEE 754标准中,符号由一位(1表示负数)表示。

因此,每个可表示的数字都存在负值和正值,包括0

这就是为什么-0+0存在。

回答原来的标题Are +0 and -0 the same?

brainslugs83 (在brainslugs83的回答中)指出了一个重要的情况,其中JS中的+0和-0不相同 – 按照函数实现:

 var sign = function(x) { return 1 / x === 1 / Math.abs(x); } 

除了标准Math.sign以外,这将返回+0和-0的正确符号。

维基百科有一个很好的文章来解释这种现象: http : //en.wikipedia.org/wiki/Signed_zero

简而言之,在IEEE浮点规范中定义了+0和-0两者。 他们两个在技术上不同,没有一个符号,这是一个整数,但实际上他们都评价为零,所以这个区别可以忽略所有的实际目的。

我们可以使用Object.is来区分+0和-0,还有一件事, NaN==NaN

 Object.is(+0,-0) //false Object.is(NaN,NaN) //true