MATLAB是member()问题

时间:2009-07-29 20:42:34

标签: matlab floating-point

以下命令返回1:

ismember(-0.6, -1:.1:.9)

但是下一个命令返回0:

ismember(-0.1, -1:.1:.9)

即使-0.1明显在-1:。1:.9。

有人知道发生了什么吗?

4 个答案:

答案 0 :(得分:4)

浮点错误。

数字0.1真的非常接近矢量中的值,但不完全正确。有些数字无法在二进制计算机中准确表示。

如果我们更了解您的情况,那么您有什么想要做的,这里可以使用许多阈值技术。

答案 1 :(得分:4)

问题是,当您从-1.0开始并重复添加0.1时,您获得的数字与直接指定-0.1时的数字略有不同。这是因为浮点错误累积。就像1/3不能用十进制精确表示(它变成0.33333 ......),许多十进制数不能用二进制表示。当转换为二进制时,0.1实际上非常接近于0.1。因为当你使用这个浮点数进行算术时会出现轻微的误差,这个小的差异会累积并变得越来越大。

来自http://www.mathworks.com/matlabcentral/newsreader/view_thread/246492

  

Ashwini Deshpande写道:

     
    
         

我有一个矩阵如下,

a = 0:0.1:1;
         

当我尝试使用以下程序查找矩阵a中是否存在0.300时,

>> [tf, loc]=ismember(0.3,a)
         

我得到了以下结果:

tf =
     0
loc =
     0
         

但它假设给我,tf = 1loc =4

         
  
     

实际上,您正在获得正确的结果。看看会发生什么:

     v=0:.1:1;
     n=0.3;
     sprintf('%30.20f\n',v(4),n)
%{
     0.30000000000000004000 % <- result from vec
     0.29999999999999999000 % <- result from handwritten number
%}
     format hex;
     [v(4),n,v(4)-n].'
%{
     3fd3333333333334 % <- vec
     3fd3333333333333 % <- num
     3c90000000000000 % <- diff
%}
     format;
     

另外,请仔细阅读http://matlabwiki.mathworks.com/MATLAB_FAQ#Why_is_0.3-0.2-0.1_not_equal_to_zero_.28or_similar.29.3F

答案 2 :(得分:1)

您所看到的是floating point representations for numbers的结果,因为数字0.1不能完全表示为浮点值。用于生成向量的colon operator通过连续添加值0.1来实现,并在过程中累积非常小的错误。由于这些错误,您认为向量中的值-0.1实际上与-0.1略有不同,并且与直接声明它时产生的-0.1值不同。举个例子:

>> format long   % Changes display to show more decimal places
>> vec = -1:0.1:0.9;
>> vec(10)+0.1

ans =

    2.775557561562891e-017

请注意,你没有得到0作为答案,因为向量中的-0.1的绝对值与你添加的0.1的值绝对不同。但是,如果您使用冒号操作符创建不带的矢量,您将获得所需的答案:

>> vec = [-1 -0.9 -0.8 -0.7 -0.6 -0.5 -0.4 -0.3 -0.2 -0.1 0 ...
          0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9];
>> ismember(-0.1,vec)

ans =

     1

简而言之,明确声明-0.1的值会产生与通过连续添加0.1到-1来生成-0.1的值相比稍微不同的数字。

答案 3 :(得分:1)

解决此问题的一个简单方法是在比较之前对数组进行舍入。 对于FKT 100,这将为您提供一个量化为2位小数的数组。

轮(FKT。*数据)./ FKT