【发布时间】:2013-06-04 17:11:14
【问题描述】:
我的 Matlab 版本是 R2012a
为什么在 Matlab 1.1-0.2 中不等于 0.9!!!!!!?
这太可怕了!
>>1.1-0.2 == 0.9
ans =
0
【问题讨论】:
-
这是由于floating point accuracy。并非所有数字都可以用 FP 数字精确表示。你永远不应该依赖上面的比较。 Somewhat related.
标签: matlab
我的 Matlab 版本是 R2012a
为什么在 Matlab 1.1-0.2 中不等于 0.9!!!!!!?
这太可怕了!
>>1.1-0.2 == 0.9
ans =
0
【问题讨论】:
标签: matlab
这不是 Matlab 问题;这是一个浮点问题。您将在 C++(或任何符合 IEEE754 的编程语言)中得到相同的结果:
#include <iostream>
int main(int, char **) {
std::cout << (1.1-0.2==0.9) << std::endl;
return 0;
}
输出:
0
这是因为 1.1 和 0.9 cannot be represented exactly in binary。这就像用十进制表示 1/3:你必须写
0.33333333333333333333333333333333333333333333333...
并无限期地继续。但无论你坚持多久,你永远都不会做对。
在浮点数中,您只能存储这么多数字,因此计算必须在某个地方停止。计算的结果其实是
>> 1.1-0.2
ans =
9.000000000000001e-01
这非常接近,但并不完全正确。
因此,在使用== 比较两个浮点数之前,您应该三思而后行;很少有 == 运算符可以在没有像您刚刚遇到的那样的“奇怪”后果的情况下应用。
最好使用舍入特定公差,例如
abs(1.1-0.2 - 0.9) <= eps(0.9)
其中eps 是一个Matlab 函数,它返回特定双精度值的spacing-between-doubles。但实际上,这不是一个包罗万象的解决方案。正确比较浮点数是一件棘手的事情。
【讨论】:
eps 用于单精度 eps('single') 和 eps('double') 用于双精度。您可以使用适当的eps 来确定两个浮点数是否足够接近。
eps(0.9) 进行比较。也许这就是你的意思,但是哦,好吧。
http://matlab.wikia.com/wiki/FAQ#Why_is_0.3-0.2-0.1_not_equal_to_zero_.28or_similar.29.3F
滚动到“为什么 0.3 - 0.2 - 0.1(或类似)不等于零?”
“一些浮点数不能精确地以二进制形式表示....如果您尝试比较两个浮点数,请在使用 == 时非常小心。另一种比较方法是检查您要比较的两个数字是否“足够接近””
【讨论】:
用于此类事情的一个很好的函数是来自文件交换的num2strexact
num2strexact(1.1-0.2)
0.9000000000000001332267629550187848508358001708984375
num2strexact(0.9)
0.90000000000000002220446049250313080847263336181640625
你看,它们不一样。
查看使用 double 与 syms 时的不同之处
num2strexact((1.1-0.2)-0.9)
1.1102230246251565404236316680908203125e-16
sym('(1.1-0.2)-0.9')
1.8367099231598242312011508394098e-40
【讨论】: