Javascript 是+;0和-0是否相同?

Javascript 是+;0和-0是否相同?,javascript,Javascript,通过阅读,可以区分,+0和-0 那么为什么+0==-0计算为true?JavaScript用于表示数字。发件人: 带符号零是带相关符号的零。在普通算术中,−0 = +0 = 0. 然而,在计算中,一些数字表示允许存在两个零,通常用−0(负零)和+0(正零)。在某些整数的有符号数表示法和大多数浮点数表示法中都会出现这种情况。数字0通常编码为+0,但可以用+0或+0表示−0 IEEE 754浮点运算标准(目前大多数计算机和支持浮点数的编程语言都使用)要求+0和+0−0零可以看作是扩展实数行的一种变体

通过阅读,可以区分,
+0
-0

那么为什么
+0==-0
计算为
true

JavaScript用于表示数字。发件人:

带符号零是带相关符号的零。在普通算术中,−0 = +0 = 0. 然而,在计算中,一些数字表示允许存在两个零,通常用−0(负零)+0(正零)。在某些整数的有符号数表示法和大多数浮点数表示法中都会出现这种情况。数字0通常编码为+0,但可以用+0或+0表示−0

IEEE 754浮点运算标准(目前大多数计算机和支持浮点数的编程语言都使用)要求+0和+0−0零可以看作是扩展实数行的一种变体,因此1/−0 = −∞ 和1/+0=+∞, 除零仅对±0/±0和±∞/±∞.

这篇文章包含了关于不同表述的更多信息

这就是为什么,从技术上讲,两个零都必须区分的原因

但是,
+0==-0
的计算结果为true。为什么是(…)

严格等式比较算法(我的重点部分是)中明确定义了这种行为:

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

(……)

  • 如果类型(x)为数字,则

  • 如果x为NaN,则返回false
  • 如果y为NaN,则返回false
  • 如果x与y的数值相同,则返回true
  • 如果x为+0,y为−0,返回true。
  • 如果x是−0,y为+0,返回true。
  • 返回false
(……)

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

从逻辑上讲,似乎将
+0
-0
视为相等。否则,我们必须在代码中考虑到这一点,我个人不想这样做;)


注意:

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

Object.is(-0, +0); // false
在JavaScript中用于表示数字类型的中,符号由位表示(1表示负数)

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


这就是为什么
-0
+0
都存在的原因。

维基百科有一篇很好的文章来解释这种现象:


简言之,+0和-0都在IEEE浮点规范中定义。它们在技术上都不同于0,没有符号,符号是一个整数,但实际上它们的计算结果都是零,因此在实际应用中可以忽略这一区别。

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

整数也可以以不同的方式存储。您可以有一个带有附加符号位的数值,因此在16位空间中,您可以存储一个15位整数值和一个符号位。在这种表示法中,值1000(十六进制)和0000都是0,但其中一个是+0,另一个是-0

这可以通过从整数值中减去1来避免,因此它的范围为-1到-2^16,但这会带来不便

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


当然,同样的规则也适用于更大的整数,但我不希望我的F被磨损

回答原始标题
时+0和-0是否相同?

brainslaugs83
(在
Spudley
的回答评论中)指出了一个重要的案例,其中JS中的+0和-0不相同-实现为函数:

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

除了标准的
数学符号之外,这将返回+0和-0的正确符号。

我将添加此作为答案,因为我忽略了@user113716的注释

您可以通过执行以下操作来测试-0:

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

isMinusZero(0); // false
isMinusZero(-0); // true

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

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

Object.is(NaN,NaN) //true

我将其归咎于严格的相等比较方法('=')。 请看第4d节


请参见

上的7.2.13严格平等比较,我刚刚遇到了一个+0和-0行为非常不同的示例:

Math.atan2(0, 0);  //returns 0
Math.atan2(0, -0); //returns Pi
小心:即使在对负数(如-0.0001)使用Math.round,它实际上也将是-0,并且可能会破坏一些后续计算,如上图所示

解决这一问题的快捷方法是执行smth,如:

if (x==0) x=0;
或者只是:

x+=0;
如果是-0,则将数字转换为+0。

2021年的答案 +0和-0是否相同

简短回答:取决于您使用的比较运算符

长答案:

到目前为止,我们基本上有4种比较类型:

  • “松散”平等
  • “严格”平等
  • (ES2015的
    Object.is
  • (ES2016)
  • 因此,只要
    Object.is(+0,-0)
    与其他对象不同。
    const x=+0,y=-0;//true->使用“松散”相等
    console.log(x==y);//true->使用“严格”相等
    console.log([x].indexOf(y));//0(true)->使用“严格”相等
    console.log(Object.is(x,y));//假的
    
    console.log(+0 == -0); // true
    
    console.log(+0 === -0); // true
    
    console.log(Object.is(+0, -0)); // false
    
    console.log([+0].includes(-0)); // true