3 个变量的总和:奇怪的行为

发布于 2024-12-07 12:10:39 字数 740 浏览 1 评论 0原文

可能的重复:
JavaScript 的数学是否已损坏?
为什么十进制数不能用二进制精确表示?

下一个代码的结果是什么:

if(0.3 == ( 0.1 + 0.1 + 0.1 ))
{
      alert(true);
}
else
{
      alert(false);
}

很奇怪,但结果将是错误的。

原因是结果

0.1+0.1+0.1

将是

0.30000000000000004

如何解释这种行为?

Possible Duplicate:
Is JavaScript's Math broken?
Why can't decimal numbers be represented exactly in binary?

What will be result of next code:

if(0.3 == ( 0.1 + 0.1 + 0.1 ))
{
      alert(true);
}
else
{
      alert(false);
}

It is strange, but result will be false.

Reason is that result of

0.1+0.1+0.1

will be

0.30000000000000004

How can be explained this behavior?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

红衣飘飘貌似仙 2024-12-14 12:10:39

这与 1/3 + 1/3 + 1/3 可能不能精确地给出小数点 1 的原因相同。如果您将 1/3 用作 .33333333,则 1/3 + 1/3 + 1/3 将为您提供 .9999999,而这并不完全是 1。

除非您确切知道自己在做什么,否则不要比较非整数数字类型是否相等。

It's the same reason 1/3 + 1/3 + 1/3 may not give you exactly 1 in decimal. If you use 1/3 as .33333333, then 1/3 + 1/3 + 1/3 will give you .9999999 which isn't exactly one.

Unless you know exactly what you're doing, don't compare non-integer numeric types for equality.

离鸿 2024-12-14 12:10:39

解释非常简单 - 阅读浮点数问题

The explanation is pretty simple - read about Floating Point Numbers Problems

妥活 2024-12-14 12:10:39

您遇到的是基本的浮点舍入错误

由于二进制数的性质,我们无法精确地表示 0.1 而不会出现一些误差。 WolframAlpha 报告十进制 0.1 等于二进制 ~0.00011001100110011...注意如何它不能在二进制数系统中有限地表示吗?这意味着我们必须决定一个停止计算这个数字的截止点,否则我们将永远留在这里。

这引入了一个错误。当代码将数字加在一起时,这个错误就会累积,导致加到总和末尾的数量非常小。这可以确保总和永远不会恰好为 0.3,这正是 IF 测试所寻找的。

然而,一些十进制数可以用二进制精确表示,例如 dec 0.5 = bin 0.1 和 dec 0.25 = bin 0.01。

我们可以使用 0.5 = (0.25 + 0.25) 与您的原始代码类似地演示这一点


如需进一步阅读,我推荐浮点指南

它很好地概述了浮点数的概念以及计算错误是如何产生的。还有一个关于 Javascript 的部分演示了如何克服您遇到的舍入错误。

What you're experiencing is a basic floating point rounding error.

We can't precisely represent 0.1 without some error due to the nature of binary numbers. WolframAlpha reports decimal 0.1 to equal binary ~0.00011001100110011... Notice how it can't be finitely represented in the binary number system? This means we have to decide on a cut off point at which to stop calculating this number otherwise we'd be here forever.

This introduces an error. And this error has accumulated as the code adds the numbers together which results in an incredibly small quantity added to the end of your sum. This ensures that the sum will never be EXACTLY 0.3, which is what the IF test is looking for.

Some decimal numbers, however, can be represented accurately in binary such as dec 0.5 = bin 0.1 and dec 0.25 = bin 0.01.

We can demonstrate this similarly to your original code by using 0.5 = (0.25 + 0.25).


For further reading on this I recommend The Floating-Point Guide.

It provides a good overview of the concept of floating point numbers and how errors in calculation can arise. There is also a section on Javascript which demonstrates how to overcome the rounding errors you're experiencing.

万劫不复 2024-12-14 12:10:39

这是由于计算机中存储的浮点数的性质决定的。不存在存储任意浮点数的精确方法。比较浮点数时,您通常会做的是查看差异是否小于某个小数 epsilon,如下所示:

function equals(f1, f2){
  var epsilon = 0.00001; //arbitrary choice
  return (f1-f2 < epsilon && f2-f1 < epsilon);
}

因此,在您的情况下,将 if(0.3 == ( 0.1 + 0.1 + 0.1 )) 更改为 if(equals 0.3, (0.1 + 0.1 + 0.1))

It's due to the nature of floats stored in computers. There is no such thing as an exact way to store an arbitrary floating point number. What you typically do when you compare floats is to see if the difference is smaller than some small number epsilon, like this:

function equals(f1, f2){
  var epsilon = 0.00001; //arbitrary choice
  return (f1-f2 < epsilon && f2-f1 < epsilon);
}

so in your case, change if(0.3 == ( 0.1 + 0.1 + 0.1 )) to if(equals 0.3, (0.1 + 0.1 + 0.1))

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文