日期:2014-05-16  浏览次数:20415 次

JavaScript中的两个“0”(翻译)
本文翻译自JavaScript’s two zeros

JavaScript has two zeros: ?0 and +0. This post explains why that is and where it matters in practice.
JavaScript 中有两个“0”: -0 和 +0 。这篇文章解释了为什么,并且指出实际生产中会造成什么影响

1.The signed zero
1.“-0”


Numbers always need to be encoded to be stored digitally. Why do some encodings have two zeros? As an example, let’s look at encoding integers as 4-digit binary numbers, via the sign-and-magnitude method. There, one uses one bit for the sign (0 if positive, 1 if negative) and the remaining bits for the magnitude (absolute value). Therefore, ?2 and +2 are encoded as follows.
Binary 1010 is decimal ?2
Binary 0010 is decimal +2
Naturally, that means that there will be two zeros: 1000 (?0) and 0000 (+0).
为了储存数字,需要将其编码为二级制,但为什么会编码出两个“0”呢,举个例子,将整数编码为4位二进制,由于整数有正有负,通过符号数值表示法,用第一位来表示符号(0 表示正数,1 表示负数),剩下的位表示数值(数的绝对值)。
所以,-2 和 +2 被编码为下面的形式:
二进制 1010 代表 -2
二进制 0010 代表 +2
很自然的,对于“2”也将出现两个:1000(-0) 和 0000(+0)


In JavaScript, all numbers are floating point numbers, encoded in double precision according to the IEEE 754 standard for floating point arithmetic. That standard handles the sign in a manner similar to sign-and-magnitude encoding for integers and therefore also has a signed zero. Whenever you represent a number digitally, it can become so small that it is indistinguishable from 0, because the encoding is not precise enough to represent the difference. Then a signed zero allows you to record “from which direction” you approached zero, what sign the number had before it was considered zero. Wikipedia nicely sums up the pros and cons of signed zeros:
在JavaScript中,所有的数字都被存储为浮点型数字,根据 IEEE 754 标准的浮点数算法编码为双精度浮点数。该标准类似于用符号数值表示法来编码整数,所以也会出现“-0”。当你要表示一个数字时,他可以表示一个小到与“0”区别不出来的数,因为编码方式无法足够精确的表示这种区别。用“-0”便可以记录一个数字在被认为是“0”之前,是“从坐标轴的那个方向”趋近真正的“0”的。关于“-0”的优劣,维基百科做了很好的总结。
引用
It is claimed that the inclusion of signed zero in IEEE 754 makes it much easier to achieve numerical accuracy in some critical problems, in particular when computing with complex elementary functions. On the other hand, the concept of signed zero runs contrary to the general assumption made in most mathematical fields (and in most mathematics courses) that negative zero is the same thing as zero. Representations that allow negative zero can be a source of errors in programs, as software developers do not realize (or may forget) that, while the two zero representations behave as equal under numeric comparisons, they are different bit patterns and yield different results in some operations.

引用
在 IEEE 754 标准中使用“-0”,更容易解决复杂数学计算中的精度等关键问题。另一方面,“-0”的概念与大多数数学领域(和数学课程)中的数学假设背道而驰,因为“-0”和“+0”是相同的。允许“-0”的存在,开发人员可能会没有认识到(或忘了)这一点,由于两个“0”的二进制表示不同,“-0”的存在,在某些计算中会产生不同的结果,导致判断两个数字相等的代码可能隐含一些错误。
此段维基百科引用的英文没有对应的中文版,所以自己做了翻译。

JavaScript goes to some lengths to hide the fact that there are two zeros.
JavaScript 做了很多工作来隐藏有两个“0”的事实。

2.Hiding the zero’s sign
2.隐藏“0”的符号

In JavaScript, you’ll usually write 0, which always means +0. But it also displays ?0 simply as 0. The following is what you see when you use any browser command line or the Node.js REPL:
通常认为,JavaScript 中显示的“0”,表示的都是“+0”。其实“-0”也直接显示为“0”,下面的例子显示了浏览器命令行和Node.js中的执行情况:
    > -0
    0

The reason is that the standard toString() method converts both zeros to the same "0".
<