+0和-0是否相同?

时间:2011-08-28 19:31:29

标签: javascript

通过ECMAScript 5.1 specification+0-0进行阅读。

为什么+0 === -0会评估为true

11 个答案:

答案 0 :(得分:165)

JavaScript使用IEEE 754 standard来表示数字。来自Wikipedia

  带有关联符号的

有符号零为零。在普通算术中,-0 = + 0 = 0.但是,在计算中,某些数字表示允许存在两个零,通常用 -0(负零) +0表示(正零)。这发生在整数的一些有符号数表示中,并且在大多数浮点数表示中。数字0通常编码为+0,但可以用+0或-0表示。

     

用于浮点运算的IEEE 754标准(目前大多数支持浮点数的计算机和编程语言都使用)需要+0和-0。零可以被认为是扩展实数线的变体,使得1 / -0 =-∞和1 / + 0 = +∞,除以0仅对于±0 /±0和±∞/±∞未定义

本文包含有关不同表示形式的更多信息。

因此,从技术上讲,这就是必须区分零的原因。

  

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

此行为在section 11.9.6中明确定义,严格的等式比较算法(重点部分是我的):

  

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

     

(...)

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

         
        
    1. 如果x为NaN,则返回false。
    2.   
    3. 如果y为NaN,则返回false。
    4.   
    5. 如果x与y的数字值相同,则返回true。
    6.   
    7. 如果x为+0且y为-0,则返回true。
    8.   
    9. 如果x为-0且y为+0,则返回true。
    10.   
    11. 返回false。
    12.   
  •   
     

(...)

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

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


注意:

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

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

答案 1 :(得分:15)

我将此作为答案添加,因为我忽略了@ user113716的评论。

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

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

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

答案 2 :(得分:3)

在用于表示JavaScript中的数字类型的IEEE 754 standard中,符号由一个位表示(1表示负数)。

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

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

答案 3 :(得分:2)

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

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

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

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

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

答案 4 :(得分:2)

回答原始标题brainslugs83

Spudley(在var sign = function(x) { return 1 / x === 1 / Math.abs(x); } 回答的评论中)指出了JS中+0和-0不相同的重要案例 - 实现为函数:

Math.sign

除了标准 let snapshotter = MKMapSnapshotter(options: options) snapshotter.startWithCompletionHandler() { snapshot, error in if error != nil { completion(image: nil, error: error) return } let image = snapshot.image let pin = MKPinAnnotationView(annotation: nil, reuseIdentifier: "") // I want to use custom annotation view instead of MKPinAnnotationView let pinImage = UIImage(named: "pinImage") UIGraphicsBeginImageContextWithOptions(image.size, true, image.scale); image.drawAtPoint(CGPointMake(0, 0)) var homePoint = snapshot.pointForCoordinate(coordinates[0]) pinImage!.drawAtPoint(homePoint) pinImage!.drawAtPoint(snapshot.pointForCoordinate(coordinates[1])) let finalImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() completion(image: finalImage, error: nil) } 之外,这将返回+0和-0的正确符号。

答案 5 :(得分:2)

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

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

Object.is(NaN,NaN) //true

答案 6 :(得分:2)

2021 年的答案

<块引用>

+0 和 -0 一样吗?

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

长答案:

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

  1. ‘宽松’平等
console.log(+0 == -0); // true
  1. ‘严格’平等
console.log(+0 === -0); // true
  1. ‘Same-value’ equalityES2015 的 Object.is
console.log(Object.is(+0, -0)); // false
  1. ‘Same-value-zero’ equality (ES2016)
console.log([+0].includes(-0)); // true

因此,只有 Object.is(+0, -0) 与其他的不同。

const x = +0, y = -0; // true                -> using ‘loose’ equality
console.log(x === y); // true                -> using ‘strict’ equality
console.log([x].indexOf(y)); // 0 (true)     -> using ‘strict’ equality
console.log(Object.is(x, y)); // false       -> using ‘Same-value’ equality
console.log([x].includes(y)); // true        -> using ‘Same-value-zero’ equality

enter image description here

答案 7 :(得分:2)

如果您需要支持 sign-0+0 函数:

var sign = x => 1/x > 0 ? +1 : -1;

它充当 Math.sign,除了 sign(0) 返回 1sign(-0) 返回 -1

答案 8 :(得分:1)

我会把它归咎于严格的平等比较方法('===')。 看第4d节 enter image description here

请参阅specification

上的 7.2.13严格的平等比较

答案 9 :(得分:0)

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

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

答案 10 :(得分:0)

我刚刚遇到了一个示例,其中+0和-0的行为确实有很大不同:

N

请注意:即使对-0.0001之类的负数使用Math.round时,它实际上也将是-0,并且可能会破坏如上所示的一些后续计算。

快速而肮脏的方法可以解决此问题,例如:

Math.atan2(0, 0);  //returns 0
Math.atan2(0, -0); //returns Pi

或者只是:

if (x==0) x=0;

在数字为-0的情况下,它将数字转换为+0。