提问人:kim kevin 提问时间:10/29/2021 更新时间:10/30/2021 访问量:433
在 MATLAB 中比较 2 个浮点数
comparing 2 floating numbers in matlab
问:
在过去的几周里,我被 Matlab 中的浮点比较问题折磨着。
我的代码涉及大量的 or .
让我发疯的是a<b
c<=d
dw = 0.001;
W1 = [0:dw:1];
W2 = [0:dw:1];
然后我们有
>>W1(418) = 0.417000000000000
>>W2(418) = 0.417000000000000
>>W1(418)>=W2(418)
ans =
logical
0
>>W2(418)>=W1(418)
ans =
logical
1
我目前处理这个问题的方法是 我定义一个错误项 .然后,每当我期待拥有时,我都会这样做。eps0 = 10^(-15)
a<=b
a<=b+eps0
但是我想知道是否有更通用的方法来解决这个问题? 我真的很感激!
答:
不,没有通用的方法可以解决浮点数比较,每种情况都不同,预期的舍入误差会随着情况而变化。
不要使用 ,请使用 : 。 是可以表示的下一个较大值(假设为正数)。这应该会处理一种形式的舍入误差。如果舍入误差累积,则需要更大的边距:例如,。eps0 = 10^(-15)
eps(b)
a<=b+eps(b)
b+eps(b)
b
a<=b+10*eps(b)
评论
这就是你告诉我们你所做的,在我的 R2018a 版本中,事情按预期进行:
>> version
ans =
'9.4.0.813654 (R2018a)'
>> dw = 0.001;
>> W1 = [0:dw:1];
>> W2 = [0:dw:1];
>> W1(418)>=W2(418)
ans =
logical
1
>> W1(418) = 0.417000000000000;
>> W2(418) = 0.417000000000000;
>> W1(418)>=W2(418)
ans =
logical
1
>> W2(418)>=W1(418)
ans =
logical
1
所以我强烈怀疑你还有什么没有告诉我们的。我可以看到得到你的结果的一种方法是,如果基础向量不是同一类型,那么 0.417 的赋值就会以不同的方式转换。例如,假设 W1 实际上是单类型而不是双类型。那么你会得到这个结果:
>> dw = 0.001;
>> W1 = single([0:dw:1]);
>> W2 = [0:dw:1];
>> W1(418) = 0.417000000000000; % converted to closest SINGLE PRECISION bit pattern
>> W2(418) = 0.417000000000000; % converted to closest DOUBLE PRECISION bit pattern
>> W1(418)>=W2(418)
ans =
logical
0
>> W2(418)>=W1(418)
ans =
logical
1
>> sprintf('%.60f\n',W1(418))
ans =
'0.416999995708465576171875000000000000000000000000000000000000
'
>> sprintf('%.60f\n',W2(418))
ans =
'0.416999999999999981792342396147432737052440643310546875000000
'
所以这里两个数字 W1(418) 和 W2(418) 实际上是不同的,因为一个存储为单精度浮点,另一个存储为双精度浮点。0.417 转换为二进制 IEEE 浮点位模式在两者之间有所不同。事实证明,单位模式的值略低于双位模式,结果完全可以解释。
所以。。。您的 W1 和 W2 向量实际上是不同的类型吗?我怀疑他们是,这让人质疑你所有的比较逻辑。正如其他人已经指出的那样,浮点算术结果通常必须持保留态度,并非常仔细地进行比较(公差等)。
评论
W1(418) == W2(418)
是真的。事实上,也是事实。我看不出您的示例会如何,因为两个数组的构造相同。all(W1==W2)
W1(418)==W2(418)
all(W1==W2)
true
~all(W1==W2)
W1
W2