我的 Matlab 版本是 R2012a
为什么在 Matlab 1.1-0.2 中不等于 0.9!!!!!!?
这太可怕了!
>>1.1-0.2 == 0.9
答案=
0
这不是 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不能用二进制精确表示。这就像用十进制表示 1/3:你必须写
0.33333333333333333333333333333333333333333333333...
并无限期地继续下去。但无论你坚持多久,你永远都不会做对。
在浮点数中,您只能存储这么多数字,因此计算必须在某个地方停止。计算的结果其实是
>> 1.1-0.2
ans =
9.000000000000001e-01
这非常接近,但并不完全正确。
==
因此,在使用比较两个浮点数之前,您应该三思而后行;很少有==
运算符可以在没有像您刚刚遇到的那样的“奇怪”后果的情况下应用。
最好使用舍入特定公差,例如
abs(1.1-0.2 - 0.9) <= eps(0.9)
其中eps
是一个 Matlab 函数,它返回特定双精度值的双精度间距。但实际上,这不是一个包罗万象的解决方案。正确比较浮点数是一件棘手的事情。
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