Pat*_*ill 4 wolfram-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"}
Run Code Online (Sandbox Code Playgroud)
我得到这个输出:
pass
pass
1.15
pass
Run Code Online (Sandbox Code Playgroud)
我只是忽略了什么?
编辑:阅读下面的有用讨论后,我更改了我的调度表以使用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]
Run Code Online (Sandbox Code Playgroud)
这似乎可以解决问题.
Sjo*_*ies 14
欢迎来到机器精度的世界.如果你仔细检查1.05 +.10和1.15,你会发现它们并不完全相同:
1.05 + .10 // FullForm
==> 1.1500000000000001`
1.15 // FullForm
==> 1.15`
Run Code Online (Sandbox Code Playgroud)
除了在使用时产生小错误外MachinePrecision,相同的浮点计算在一天的不同时间可能会产生略微不同的结果.这不是一个错误,而是现代硬件浮点架构如何工作的副产品
这意味着您不应该使用这样的操作ReplaceAll取决于知道MachinePrecision数字的确切值.使用==(和===)可能没问题,因为它们忽略了最后7个(分别为1个)数字的二进制数字MachinePrecision.
使用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"}
Run Code Online (Sandbox Code Playgroud)
更新:每个计算机科学家应该知道的关于浮点运算的内容给出了关于浮点运算的更多警告.例如,第80页给出了IEEE 754的不同实现如何给出略微不同的结果的示例,即使它们是标准兼容的