是什么导致了这个奇怪的 Mathematica 结果?

发布于 2024-10-20 02:01:27 字数 591 浏览 0 评论 0原文

我在 Mathematica 8 中遇到了一个看似错误的问题。我在网上找不到任何与之相关的内容,但我承认我不太确定要搜索什么。

如果我运行这个语句:

0.05 + .10 /. {0.15 -> "pass"}
1.04 + .10 /. {1.14 -> "pass"}
1.05 + .10 /. {1.15 -> "pass"}
1.15 /. {1.15 -> "pass"}

我得到这个输出:

pass

pass

1.15

pass

我只是忽略了一些东西吗?

编辑:阅读下面有用的讨论后,我更改了调度表以使用 Which 语句:

f[x_] := Which[x == 1.05, -1.709847, x == 1.10, -1.373823, 
  x == 1.15, -1.119214, x == 1.20, -0.9160143, x == 1.25, -0.7470223, x == 1.30, -0.6015966]

这似乎可以解决问题。

I've run into what seems like a bug in Mathematica 8. I can't find anything related to it online, but I admit I'm not exactly sure what to search for.

If I run this statement:

0.05 + .10 /. {0.15 -> "pass"}
1.04 + .10 /. {1.14 -> "pass"}
1.05 + .10 /. {1.15 -> "pass"}
1.15 /. {1.15 -> "pass"}

I get this output:

pass

pass

1.15

pass

Am I just overlooking something?

Edit: After reading the helpful discussion below, I changed my dispatch table to use a Which statement instead:

f[x_] := Which[x == 1.05, -1.709847, x == 1.10, -1.373823, 
  x == 1.15, -1.119214, x == 1.20, -0.9160143, x == 1.25, -0.7470223, x == 1.30, -0.6015966]

This seems to do the trick.

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

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

发布评论

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

评论(3

瑾夏年华 2024-10-27 02:01:27

欢迎来到机器精度的世界。如果您更仔细地检查 1.05 +.10 和 1.15,您会发现它们并不完全相同:

1.05 + .10 // FullForm

==> 1.1500000000000001`

1.15 // FullForm

==> 1.15`

Welcome to the world of machine precision. If you examine 1.05 +.10 and 1.15 more closely, you'll see that they're not quite the same:

1.05 + .10 // FullForm

==> 1.1500000000000001`

1.15 // FullForm

==> 1.15`
终难愈 2024-10-27 02:01:27

除了使用 MachinePrecision 时产生小错误之外,相同的浮点计算在一天中的不同时间可能会产生略有不同的结果。这不是一个错误,而是现代技术的副产品硬件浮点架构工作

这意味着您不应使用像 ReplaceAll 这样依赖于了解 MachinePrecision 数字的精确值的操作。使用 == (和 ===)可能没问题,因为它们忽略 MachinePrecision 数字的最后 7 位(分别为 1)二进制数字。

无论一天中的什么时间,使用 Mathematica 算术都应该给出准确的结果,您可以将其用于您的示例,如下所示(10 位有效数字)

0.05`10 + .10`10 /. {0.15`10 -> "pass"}
1.04`10 + .10`10 /. {1.14`10 -> "pass"}
1.05`10 + .10`10 /. {1.15`10 -> "pass"}
1.15`10 /. {1.15`10 -> "pass"}

更新每个计算机科学家都应该了解浮点运算 给出了一些有关浮点运算的更多警告。例如,第 80 页给出了 IEEE 754 的不同实现如何给出略有不同的结果的示例,尽管它们符合标准

In addition to incurring small errors when using MachinePrecision, the same floating-point calculation can produce slightly different results at different times of the day. This is not a bug, but rather a by-product of how modern hardware floating-point architectures work

This means you should not use operations like ReplaceAll that depend on knowing exact value of MachinePrecision numbers. Using == (and ===) might be OK because they ignore last 7 (respectively 1) binary digit of MachinePrecision numbers.

Using Mathematica arithmetic should give exact results regardless of time of day, you could use it for your example as follows (10 significant digits)

0.05`10 + .10`10 /. {0.15`10 -> "pass"}
1.04`10 + .10`10 /. {1.14`10 -> "pass"}
1.05`10 + .10`10 /. {1.15`10 -> "pass"}
1.15`10 /. {1.15`10 -> "pass"}

Update: What Every Computer Scientist Should Know About Floating-Point Arithmetic gives some more caveats about floating point arithmetic. For instance, page 80 gives examples of how different implementations of IEEE 754 give slightly different results, even despite being standard compliant

书间行客 2024-10-27 02:01:27

您的替换仅适用于完全匹配,而您的 While 语句使用 Equal。您也可以使用 Equal 来使基于规则的方法发挥作用。

0.05 + .10 /. {x_ /; x == 0.15 -> "pass"}
1.04 + .10 /. {x_ /; x == 1.14 -> "pass"}
1.05 + .10 /. {x_ /; x == 1.15 -> "pass"}
1.15 /. {x_ /; x == 1.15 -> "pass"}

Your replacements only work on exact matches, whereas your While statement uses Equal. You can make the rule based approach work by using Equal as well.

0.05 + .10 /. {x_ /; x == 0.15 -> "pass"}
1.04 + .10 /. {x_ /; x == 1.14 -> "pass"}
1.05 + .10 /. {x_ /; x == 1.15 -> "pass"}
1.15 /. {x_ /; x == 1.15 -> "pass"}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文