为什么JavaScript在显示大数字时不准确?

4
所以在JavaScript中,111111111111111111111 == 111111111111111110000。只需键入任何长数字-至少约17位数字-即可看到其效果;)
这是因为JavaScript使用双精度浮点数,并且某些非常长的数字文字不能准确表示。相反,这些数字会被四舍五入到最接近的可表示数字。例如,参见什么是JavaScript的最高整数值,Number可以达到而不失去精度? 然而,根据IEEE-754进行计算,我发现[111111111111111106560,111111111111111122944]内的每个数字都将在内部替换为111111111111111114752。但是,它并没有显示为...4752这个数字,而是显示为111111111111111110000。因此,JavaScript显示了那些尾随的零,从而使真实行为变得模糊不清。这特别令人讨厌,因为像263这样的偶数,其表示精度很高,也会像上述描述一样“四舍五入”。
所以,我的问题是:为什么JavaScript在显示数字时会像这样表现?

由于该范围内的所有整数被等价地处理,因此其中任意一个可以被任意选择显示。在精度范围之外的所有数字都显示为零是有意义的。 - Barmar
我敢打赌在ECMAScript规范中有规定要使用零,但我不太感兴趣去查找它。 - Barmar
是的,那可能是这种情况。我只是想知道是否有人知道背后的确切原因,因为例如在 C 编程语言中,我从来没有看到过这样奇怪的零(使用 printf("%lf", n);)。 - purefanatic
感谢Jan Doggen和Paul改进我的问题。我需要再斟酌一下措辞。 - purefanatic
1个回答

4

JavaScript中的整数只能是+/-253,即:

9007199254740992

你的一个数字是

111111111111111106560

远超出可以准确表示为整数的数字范围。

这遵循IEEE 754规范:

  • 符号位:1位
  • 指数宽度:11位
  • 有效位精度:53位(其中52位明确存储)

编辑

数字的显示有时会被JavaScript引擎四舍五入,但可以使用toFixed方法覆盖它。(警告,已知在某些IE版本下,toFixed存在问题)。

在控制台中输入:

111111111111111122944..toFixed(0)

"111111111111111114752" 可能是一个表示数字的字符串。

有许多整数可以使用IEEE-754双精度表示准确地表示。它们不一定有邻居;-)这些整数是我的问题的主题 - 我认为它们应该被准确地显示。 - purefanatic
现在这是个好消息,至少能以某种方式显示它们对吧!我不知道呢! - purefanatic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接