什么导致这个奇怪的Mathematica结果?
我遇到了Mathematica 8中的一个bug。我在网上找不到任何与它有关的东西,但我承认我并不确定要搜索什么。
如果我运行这个声明:
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
我只是俯视一些东西?
编辑:在阅读了下面有用的讨论之后,我改变了我的调度表来改为使用Where语句:
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]
这似乎有伎俩。
欢迎来到机器精度的世界。 如果你仔细检查1.05 +.10和1.15,你会发现它们并不完全相同:
1.05 + .10 // FullForm
==> 1.1500000000000001`
1.15 // FullForm
==> 1.15`
除了在使用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的不同实现如何给出稍微不同的结果的例子,即使是符合标准的
您的替换仅适用于完全匹配,而您的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"}
链接地址: http://www.djcxy.com/p/35545.html