Javascript +0 和 -0 一样吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7223359/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 01:23:25  来源:igfitidea点击:

Are +0 and -0 the same?

javascript

提问by Randomblue

Reading through the ECMAScript 5.1 specification, +0and -0are distinguished.

通过阅读的ECMAScript 5.1规范+0-0被区分。

Why then does +0 === -0evaluate to true?

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

回答by Felix Kling

JavaScript uses IEEE 754 standardto represent numbers. From Wikipedia:

JavaScript 使用IEEE 754 标准来表示数字。来自维基百科

Signed zerois zero with an associated sign. In ordinary arithmetic, ?0 = +0 = 0. However, in computing, some number representations allow for the existence of two zeros, often denoted by ?0 (negative zero)and +0 (positive zero). This occurs in some signed number representations for integers, and in most floating point number representations. The number 0 is usually encoded as +0, but can be represented by either +0 or ?0.

The IEEE 754 standard for floating point arithmetic (presently used by most computers and programming languages that support floating point numbers) requires both +0 and ?0. The zeroes can be considered as a variant of the extended real number line such that 1/?0 = ?∞ and 1/+0 = +∞, division by zero is only undefined for ±0/±0 and ±∞/±∞.

有符号零是具有相关符号的零。在普通算术中,?0 = +0 = 0。然而,在计算中,一些数字表示允许存在两个零,通常用?0(负零)+0(正零)表示。这发生在整数的一些有符号数表示中,以及大多数浮点数表示中。数字 0 通常编码为 +0,但可以用 +0 或 ?0 表​​示。

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

The article contains further information about the different representations.

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

So this is the reason why, technically, both zeros have to be distinguished.

所以这就是为什么在技术上必须区分两个零的原因。

However, +0 === -0evaluates to true. Why is that (...) ?

但是,+0 === -0评估为真。这是为什么 (...) ?

This behaviour is explicitly defined in section 11.9.6, the Strict Equality Comparison Algorithm(emphasis partly mine):

这种行为在第 11.9.6 节中明确定义,严格相等比较算法(部分强调我的):

The comparison x === y, where xand yare values, produces trueor false. Such a comparison is performed as follows:

(...)

  • If Type(x) is Number, then

    1. If x is NaN, return false.
    2. If y is NaN, return false.
    3. If x is the same Number value as y, return true.
    4. If x is +0 and y is ?0, return true.
    5. If x is ?0 and y is +0, return true.
    6. Return false.

(...)

比较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. 返回假。

(……)

(The same holds for +0 == -0btw.)

+0 == -0顺便说一句,这同样适用。)

It seems logically to treat +0and -0as equal. Otherwise we would have to take this into account in our code and I, personally, don't want to do that ;)

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



Note:

笔记:

ES2015 introduces a new comparison method, Object.is. Object.isexplicitly distinguishes between -0and +0:

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

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

回答by laktak

I'll add this as an answer because I overlooked @user113716's comment.

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

You can test for -0 by doing this:

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

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

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

回答by Foxcode

I just came across an example where +0 and -0 behave very differently indeed:

我刚刚遇到一个例子,其中 +0 和 -0 的行为确实非常不同:

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

Be careful: even when using Math.round on a negative number like -0.0001, it will actually be -0 and can screw up some subsequent calculations as shown above.

小心:即使在像 -0.0001 这样的负数上使用 Math.round 时,它实际上也会是 -0,并且可能会破坏一些后续计算,如上所示。

Quick and dirty way to fix this is to do smth like:

解决这个问题的快速而肮脏的方法是这样做:

if (x==0) x=0;

or just:

要不就:

x+=0;

This converts the number to +0 in case it was -0.

如果它是 -0,这会将数字转换为 +0。

回答by Arnaud Le Blanc

In the IEEE 754 standardused to represent the Number type in JavaScript, the sign is represented by a bit (a 1 indicates a negative number).

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

As a result, there exists both a negative and a positive value for each representable number, including 0.

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

This is why both -0and +0exist.

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

回答by B M

Answering the original title Are +0 and -0 the same?:

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

brainslugs83(in comments of answer by Spudley) pointed out an important case in which +0 and -0 in JS are not the same - implemented as function:

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

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

This will, other than the standard Math.signreturn the correct sign of +0 and -0.

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

回答by terryc

We can use Object.isto distinguish +0 and -0, and one more thing, NaN==NaN.

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

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

Object.is(NaN,NaN) //true

回答by GolezTrol

There are two possible values (bit representations) for 0. This is not unique. Especially in floating point numbers this can occur. That is because floating point numbers are actually stored as a kind of formula.

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

Integers can be stored in separate ways too. You can have a numeric value with an additional sign-bit, so in a 16 bit space, you can store a 15 bit integer value and a sign-bit. In this representation, the value 1000 (hex) and 0000 both are 0, but one of them is +0 and the other is -0.

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

This could be avoided by subtracting 1 from the integer value so it ranged from -1 to -2^16, but this would be inconvenient.

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

A more common approach is to store integers in 'two complements', but apparently ECMAscript has chosen not to. In this method numbers range from 0000 to 7FFF positive. Negative numbers start at FFFF (-1) to 8000.

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

Of course, the same rules apply to larger integers too, but I don't want my F to wear out. ;)

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

回答by Bar Horing

I'd blame it on the Strict Equality Comparison method ( '===' ). Look at section 4d enter image description here

我将其归咎于严格相等比较方法( '===' )。看第 4d 节 在此处输入图片说明

see 7.2.13 Strict Equality Comparisonon the specification

参见规范上的7.2.13 严格相等比较

回答by Spudley

Wikipedia has a good article to explain this phenomenon: http://en.wikipedia.org/wiki/Signed_zero

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

In brief, it both +0 and -0 are defined in the IEEE floating point specifications. Both of them are technically distinct from 0 without a sign, which is an integer, but in practice they all evaluate to zero, so the distinction can be ignored for all practical purposes.

简而言之,IEEE 浮点规范中定义了 +0 和 -0。从技术上讲,它们都与没有符号的 0 不同,0 是整数,但实际上它们都计算为零,因此出于所有实际目的可以忽略这种区别。