为什么在 Javascript 中添加两位小数会产生错误的结果?

IT技术 javascript math floating-point addition decimal
2021-03-12 15:29:06

可能的重复:
JavaScript 的数学有问题吗?

为什么 JS 搞砸了这个简单的数学?

console.log(.1 + .2)  // 0.3000000000000004
console.log(.3 + .6)  // 0.8999999999999999

第一个示例大于正确结果,而第二个示例小于正确结果。???你如何解决这个问题?在执行运算之前,您是否必须始终将小数转换为整数?我是否只需要担心添加 (* 和 / 在我的测试中似乎没有相同的问题)?

我已经在很多地方寻找答案。一些教程(如购物车表单)假装问题不存在,只是将值加在一起。Gurus 为各种数学函数提供了复杂的例程,或者顺便提到 JS“做得不好”,但我还没有看到解释。

5个回答

这不是 JS 问题,而是更通用的计算机问题。浮点数无法正确存储所有十进制数,因为它们以二进制形式存储内容 例如:

0.5 is store as b0.1 
but 0.1 = 1/10 so it's 1/16 + (1/10-1/16) = 1/16 + 0.0375
0.0375 = 1/32 + (0.0375-1/32) = 1/32 + 00625 ... etc

so in binary 0.1 is 0.00011... 

但那是无止境的。除了计算机必须在某个时候停止。因此,如果在我们的示例中,我们在 0.00011 处停止,我们将得到 0.09375 而不是 0.1。

无论如何,关键是,这不取决于语言,而取决于计算机。取决于语言的是您如何显示数字。通常,该语言会将数字四舍五入为可接受的表示形式。显然 JS 没有。

所以你必须做的(内存中的数字足够准确)只是在将它们转换为文本时以某种方式告诉 JS 以“很好地”舍入数字。

您可以尝试使用该sprintf功能可以很好地控制如何显示数字。

来自浮点指南

为什么我的数字,比如 0.1 + 0.2 加起来是一个不错的回合 0.3,而是我得到一个奇怪的结果,比如 0.30000000000000004?

因为在内部,计算机使用的格式(二进制浮点数)根本无法准确表示像 0.1、0.2 或 0.3 这样的数字。

在编译或解释代码时,您的“0.1”已经四舍五入到该格式中最接近的数字,即使在计算发生之前,这也会导致一个小的舍入误差。

该站点有详细的解释以及有关如何解决问题的信息(以及如何确定它是否是您的情况的问题)。

更简单的答案。
2021-05-01 15:29:06
有关此float-point-gui.de/basic 的更多信息
2021-05-04 15:29:06

这不是 javascript 唯一的限制,它适用于所有浮点计算。问题是 0.1、0.2 和 0.3 不能完全表示为 javascript(或 C 或 Java 等)浮点数。因此,您看到的输出是由于这种不准确。

尤其是只有某些 2 的幂的和才可以精确表示。0.5 = =0.1b = 2^(-1), 0.25=0.01b=(2^-2), 0.75=0.11b = (2^-1 + 2^-2) 都可以。但是 1/10 = 0.000110001100011..b 只能表示为 2 的无限幂之和,语言在某些时候将其切断。正是这种斩波导致了这些轻微的错误。

这对于所有编程语言都是正常的,因为并非所有十进制值都可以用二进制精确表示。了解每位计算机科学家都应该了解的有关浮点运算的知识

它与计算机如何处理浮点数有关。您可以在此处阅读更多相关信息:http : //docs.sun.com/source/806-3568/ncg_goldberg.html