【问题标题】:Okay to use double for == comparison and indexing?可以使用 double 进行 == 比较和索引吗?
【发布时间】:2014-08-12 13:32:11
【问题描述】:

In this answer gire 提到在比较双打时最好不要使用==

当使用start:step:stop 表示法在for 循环中创建增量变量时,它的类型将是double。如果要使用此循环变量进行索引和== 比较,是否会因浮点精度而导致问题?!

应该使用整数吗?如果是这样,有没有办法用s:s:s 表示法做到这一点?

这是一个例子

a = rand(1, 5);

for ii = length(a):-1:1
  if (ii == 1)      % Comparing var of type double with ==
    b = 0;          
  else
    b = a(ii);      % Using double for indexing
  end

  ...               % Code

end

【问题讨论】:

  • 如果您的增量本身是整数,我认为这并不适用。我的意思是,我猜它可能会出错,但由于您没有处理任何小数点,我认为您的计算机无法准确表示所有这些数字,因此比较应该成立。问题不在于 double 类型本身,而在于存在以十进制形式表示的分数(具有有限精度)可能需要更高的精度(甚至无限精度)才能以二进制表示。如果您在循环中通过-1,我认为使用== 是安全的
  • Octave 的常见问题解答中有一个条目,Why is this floating point computation wrong?,它解释了一切。它链接到一篇非常好的文章What Every Computer Scientist Should Know About Floating Point Arithmetic
  • 但是请注意,在那个答案中,Gire 没有谈论循环索引。您在该问题中检查的条件是不能保证是“整数”(a 是未指定计算的结果),因此他的观点在这种情况下肯定是有效的。

标签: matlab loops octave


【解决方案1】:

请注意,浮点双精度规范使用 52 位来存储尾数(小数点后的部分),因此您可以准确地表示范围内的任何整数

-4503599627370496 <= x <= 4503599627370496

注意这个比一个int32的范围要大,只能表示

      -2147483648 <= x <= 2147483647

如果您只是使用双精度作为循环变量,并且仅以整数步长递增它,并且您没有超过 4,503,599,627,370,496,那么您可以使用双精度,并使用 == 比较双精度。

人们建议不使用双精度的一个原因是您不能准确表示一些常见的小数,例如0.1 没有精确的双精度表示。因此,如果您使用货币值,最好将数据单独存储为 int 并记住 10x 或 100x 或其他的比例因子。

有时直接比较浮点数是否相等并不好,因为舍入问题会导致两个浮点数不相等,即使数字在数学上相等。这通常发生在数字不能精确地表示为浮点数时,或者当数字之间存在显着的大小差异时,例如

>> 0.3 - 0.2 == 0.1
ans =
     0

【讨论】:

    【解决方案2】:
    • 如果您使用整数步长在整数边界之间建立索引(即使变量类实际上是 double),也可以使用 == 与其他整数进行比较。
    • 如果您真的想要安全,可以强制转换索引。

    例如:

    for ii = int16(length(a):-1:1)
        if (ii == 1)
           b = 0;
        end
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-04-21
      • 2023-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-12
      • 1970-01-01
      • 2012-09-25
      相关资源
      最近更新 更多