我在Matlab中使用find函数得到了一个非常奇怪的错误。看看这个!
A = 0:0.1:10;
现在,如果我执行以下操作,我会得到预期的行为:
find(A==5.6)
ans = 57
但如果我这样做:
find(A==5.9)
ans =
Empty matrix: 1-by-0
任何人都知道为什么?这很奇怪。
提前致谢!
答案 0 :(得分:1)
以下是大多数程序员的常识:
a = 0.3;
b = 3 * 0.1;
a == b
ans =
0
这是因为0.1
无法准确表示为二进制数,因此3*0.1
几乎等于0.3
,但是四舍五入错误。
然而,您显然可以执行以下操作:
a = 0.3;
a == 0.3
ans =
1
然而,你的问题比这更复杂......你做了:
A = 0:0.1:10;
尽管您可能会想到,但MATLAB不会创建值[0 0.1 0.2 ...]
,而是创建[0 0+0.1 0+0.1+0.1 0+0.1+0.1+0.1 ...]
的内容(但不是真的,请参阅底部的更新 )。
为了说明这一点,您可以查看以下示例:
A = 0:0.1:0.4;
find(A == 0.3)
ans =
Empty matrix: 1-by-0
find(A == 0.1+0.1+0.1)
ans =
4
然而,这并没有涵盖所有方面:
A = 5.8:0.1:6
A =
5.8000 5.9000 6.0000
find(A == 5.9)
ans =
2
%% Found it!
A = 5.8:0.1:6.1
A =
5.8000 5.9000 6.0000 6.1000
find(A == 5.9)
ans =
Empty matrix: 1-by-0
%% Didn't find it!
find(A == 5.8+0.1)
ans =
2
%% Found it again!
对于记录,linspace
会产生相同的结果。
A = linspace(5.8, 6.0, 3)
A =
5.8000 5.9000 6.0000
find(A == 5.9)
ans =
2
A = linspace(5.8, 6.1, 4)
A =
5.8000 5.9000 6.0000 6.1000
find(A == 5.9)
ans =
Empty matrix: 1-by-0
find(A == 5.8+0.1)
ans =
2
那么,发生了什么?以下两个实际上是否相同:x = [a:b:c]
和y = linspace(a,c,(c-a)/b+1)
?
A = 5.8:0.1:6.1
A =
5.8000 5.9000 6.0000 6.1000
B = linspace(5.8,6.1,4)
B =
5.8000 5.9000 6.0000 6.1000
A == B
ans =
1 1 1 1
可能看起来那样......但答案是否定的,它们不一样!
x = -0.1:0.1:0.3
x =
-0.1000 0 0.1000 0.2000 0.3000
y = linspace(-0.1,0.3,5)
y =
-0.1000 0 0.1000 0.2000 0.3000
x == y
ans =
1 1 0 0 1
那么,当你A = 5.8:0.1:6
时会发生什么?数字是如何创建的?如何解释以下内容?
A = 5.8:0.1:6;
B = 5.8:0.1:6.1;
A(2)-B(2)
ans =
8.8818e-016
eps(5.9)
ans =
8.8818e-016
抵消执行[0 0+0.1 0+2*0.1 ... 0+k*0.1]
“为了抵消这种错误累积,COLON算子的算法决定:
通过添加整数来计算输出向量的前半部分 步数的倍数到左手端点。下半场是 通过从右手减去步数的倍数来计算 端点。
还要看here。
当然,课程不是使用x == y
来比较浮点数,而是(x - y) < tolerance
。
答案 1 :(得分:0)
正如评论中已经指出的那样,这是一个浮点问题。
如果您确实希望以这种方式使用find
,请尝试使用linspace
代替:
来创建数组:
<强>之前:强>
>> A = 0:0.1:10;
>> find(A==5.6)
ans =
57
>> find(A==5.9)
ans =
Empty matrix: 1-by-0
<强>后:强>
>> A = linspace(0, 10, 101);
>> find(A==5.6)
ans =
57
>> find(A==5.9)
ans =
60