+ 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
,其中x
和y
是值,产生true或false 。 这样的比较如下进行:(……)
如果Type(x)是Number,那么
- 如果x是NaN,则返回false。
- 如果y是NaN,则返回false。
- 如果x与y的Number值相同,则返回true。
- 如果x是+0,y是-0,则返回true。
- 如果x是-0,y是+0,则返回true。
- 返回false。
(……)
(这同样适用于+0 == -0
btw。)
从逻辑上来看, +0
和-0
是相等的。 否则,我们将不得不在我们的代码中考虑到这一点,我个人不希望这样做;)
注意:
ES2015引入了一种新的比较方法Object.is
。 Object.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