33

谁能向我解释为什么 9999999999999999 转换为 10000000000000000?

alert(9999999999999999); //10000000000000000

http://jsfiddle.net/Y2Vb2/

4

6 回答 6

41

Javascript 没有整数,只有 64 位浮点数 - 而且您已经用完了浮点精度。

在 Java 中查看类似问题:为什么 Double.parseDouble 将 9999999999999999 变为 10000000000000000?

于 2012-11-17T09:52:02.073 回答
20
  1. JavaScript 只有浮点数,没有整数。

  2. 阅读每位计算机科学家应了解的关于浮点运算的知识

    摘要:浮点数只包括有限的精度,超过 15 位(左右),你会得到四舍五入。

于 2012-11-17T09:55:33.277 回答
11

9999999999999999在 JavaScript 内部被视为浮点数。它不能在 IEEE 754 双精度中准确表示,因为它需要 54 位精度(位数为 log2(9999999999999999) = 53,150849512...并且由于不存在小数位,因此必须将结果向上取整)而 IEEE 754 仅提供 53 位(1 个隐含位 + 52 个显式存储的尾数位) - 少了一位。因此,数字只是四舍五入。

由于在这种情况下只丢失了一位,因此即使是 54 位数字也可以精确表示,因为它们仍然包含0在丢失的位中。考虑到 IEEE 754 的默认无偏舍入模式,奇数 54 位数字被舍入到恰好是 53 位偶数的两倍的最接近的值。

于 2012-11-17T10:00:32.050 回答
5
于 2018-05-07T11:45:41.127 回答
3

问题:有时 JavaScript 计算似乎产生“不准确”的结果,例如 0.362*100 产生 36.199999999999996。我怎样才能避免这种情况?

答:JavaScript 在内部以双精度浮点格式存储所有数字,尾数为 52 位,指数为 11 位(用于存储数值的 IEEE 754 标准)。这种数字的内部表示可能会导致上述意外结果。大多数大于 253 = 9007199254740992 的整数不能以这种格式精确表示。同样,许多小数/分数(例如 0.362)无法准确表示,导致上述示例中的感知“不准确”。为了避免这些“不准确”的结果,您可能希望将结果四舍五入到您使用的数据的精度。

http://www.javascripter.net/faq/accuracy.htm

于 2012-11-17T10:29:55.227 回答
0

二进制形式的9999999999999999100011100001101111001001101111110000001111111111111111 ,它有 54 位数字。

下面我们将把这个数字转换为 Javascript IEEE-754,它有 1 位符号,11 位二进制偏移格式的尾数和 52 位数字本身的符号。

在二进制形式中,第一个数字始终为1,因此 Javascript 在保存为 IEEE-754 格式时会省略尾数中数字的第一个数字。因此,我们将有00011100001101111001001101111110000001111111111111111作为尾数,这是 53 位数字,至于数字我们只能保留 52 位数字,我们将数字四舍五入删除最后一位数字000111000011011110010010000000000000000000000000000000000000

二进制形式的最终数字将为 1 0001110000110111100100110111111000001000000000000000 0,十进制形式为 10000000000000000

1 是第一个未写入尾数 52 位的数字,然后是 52 位尾数和一个 0,使其返回 54 位,即 十进制的10000000000000000

除非您阅读这篇漂亮的文章,否则这可能很难理解

于 2021-11-12T14:32:02.670 回答