是什么导致了这个奇怪的 Mathematica 结果?
我在 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
欢迎来到机器精度的世界。如果您更仔细地检查 1.05 +.10 和 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:
除了使用
MachinePrecision
时产生小错误之外,相同的浮点计算在一天中的不同时间可能会产生略有不同的结果。这不是一个错误,而是现代技术的副产品硬件浮点架构工作这意味着您不应使用像
ReplaceAll
这样依赖于了解MachinePrecision
数字的精确值的操作。使用==
(和===
)可能没问题,因为它们忽略MachinePrecision
数字的最后 7 位(分别为 1)二进制数字。无论一天中的什么时间,使用 Mathematica 算术都应该给出准确的结果,您可以将其用于您的示例,如下所示(10 位有效数字)
更新:每个计算机科学家都应该了解浮点运算 给出了一些有关浮点运算的更多警告。例如,第 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 workThis means you should not use operations like
ReplaceAll
that depend on knowing exact value ofMachinePrecision
numbers. Using==
(and===
) might be OK because they ignore last 7 (respectively 1) binary digit ofMachinePrecision
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)
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
您的替换仅适用于完全匹配,而您的 While 语句使用
Equal
。您也可以使用Equal
来使基于规则的方法发挥作用。Your replacements only work on exact matches, whereas your While statement uses
Equal
. You can make the rule based approach work by usingEqual
as well.