【问题标题】:Floating point error in MATLAB - linearly spaced vectors [duplicate]MATLAB中的浮点错误 - 线性间隔向量
【发布时间】:2015-04-26 18:58:48
【问题描述】:

操作系统:Win 7 64 位。 Matlab:2014a,2015a

当我按如下方式创建向量时:

a = 0.2:0.2:1

我明白了:

a = 0.2000    0.4000    0.6000    0.8000    1.0000

这是预期的。现在,当我想查看向量中是否存在 0.6 时,我输入:

a == 0.6

我得到:0 0 0 0 0

find(a == 0.6) 也返回一个Empty matrix: 1-by-0

这些都是意料之外的。它能够找到所有其他值,但是对于 0.6 存在问题。我认为虽然创建了 0.6,但它实际上是 0.600000000000000001 或类似的东西,这是一个问题。您可以看到a > 0.6 是这种情况,并且会得到0 0 1 1 1

1-首先为什么会这样?

2-Second 我们能在 Matlab 中看到一个数字的整个值吗?如果可以,它的功能或设置是什么?

我使用linspace 创建了相同的向量,但这也没有帮助。我通过键入:a = roundn(a, -10) 找到了解决方案。但是,我认为一开始就不需要这样的解决方案。

3-有没有更好的方法让 Matlab 产生精确的值?

感谢大家的帮助。

【问题讨论】:

  • 使用符号数学。类型 double 不能准确表示小数。
  • 欢迎使用浮点编程。另请参阅:Why is 24.0000 not equal to 24.0000 in MATLAB? 并尝试 a = 0.2:0.2:1; a(3)-0.6
  • 谢谢你们。所以我认为这是一个问题,但如果是这样,那么它应该适用于每个值。它不适用于我的向量中的其他值。只到 0.6。严重的是,如果是这种情况,那我该怎么做比较?突然之间,一个简单的比较变成了一件麻烦事。

标签: matlab vector decimal-point significant-digits


【解决方案1】:

首先,阅读有关浮点值的 MATLAB 文档,特别注意浮点误差和精度部分: MATLAB Floating Point

您遇到了一个非常常见的浮点精度问题。重要的是要认识到您实际上并不是在比较:

>> a = 0.6;
>> b = 0.6;
>> a == b
   ans = 1

相反,您实际上是在比较:

>> a = 0.6;
>> b = 0.2 + 0.2 + 0.2;
>> a == b
   ans = 0

这里出现明显的逻辑谬误的原因是算术实际上并不相等。值 0.60.2 都以双精度浮点数表示为最接近的可能值,差异称为“浮点错误”。

观察错误很简单:

>> a = 0.6;
>> b = 0.2 + 0.2 + 0.2;
>> a - b
   ans = -1.110223024625157e-16

最简单的解决方案是在您的标量和向量上使用round() 以达到相同的精度,然后执行比较:

>> a = 0.6;
>> b = [ 0.2 : 0.2 : 1 ];
>> roundn ( a , -10) == roundn ( b , -10 )
   ans = 0 0 1 0 0

【讨论】:

  • 我明白了。我感谢您的帮助。但是为什么对于其他值它可以找到它而对于 0.6 却找不到呢?不应该是一致的,也不能找到其他人吗?例如 a == 0.8?
  • 我不确定你的意思。如果你尝试a = 0.8;b=0.2:0.2:1;,然后尝试a==b,你仍然会得到ans = 0 0 0 0 0
  • 嗯,不,我完全按照你的做法得到了:0 0 0 1 0
  • 更正,我得到的结果和你一样。这实际上是有道理的。 eps(0.8) ans = 1.110223024625157e-16eps(0.2) ans = 2.775557561562891e-17eps(0.2)*4 ans = 1.110223024625157e-16。基本上,0.2*4 和 0.8 具有相同的浮点精度。
  • 哇。太棒了。感谢您指出这一点。确实eps(0.6) = 1.1102e-16 , eps(0.2)*3 = 8.3267e-17。所以为了进行数字比较,最安全的方法是使用roundn?这是你做的吗?还有其他解决方案吗?
猜你喜欢
  • 1970-01-01
  • 2023-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-15
  • 1970-01-01
  • 2011-05-20
相关资源
最近更新 更多