比较两个 32 位浮点值的 Delta 值可以有多低?

问题描述 投票:0回答:2

我有一套 240 个具有不同抽头数的 FIR 滤波器卷积单元测试。

所有测试都通过了,当我正在完善时,我注意到比较的增量是

1E-04f

我将其降低到

1E-05f
,有效,尝试过
1E-06f
,但通过率是< 50% then.

1E-05f 示例:

   index         expected           actual       difference    match
   0   -2.7051452E-34   -2.7051452E-34    0.000000E+000     True
   1    0.00011297482    0.00011297482    0.000000E+000     True
   2    0.00022594964    0.00022594964    0.000000E+000     True
   3    -0.0010179491    -0.0010179491    0.000000E+000     True
   4    -0.0022618477    -0.0022618477    0.000000E+000     True
   5     0.0019123415     0.0019123415    0.000000E+000     True
   6       0.00608653       0.00608653    0.000000E+000     True
   7    -0.0052014478    -0.0052014478    0.000000E+000     True
   8     -0.016489426     -0.016489424    1.862645E-009     True
   9      0.009599558      0.009599558    0.000000E+000     True
  10      0.035688534      0.035688538    3.725290E-009     True
  11     -0.026160091     -0.026160091    0.000000E+000     True
  12      -0.08800873      -0.08800873    0.000000E+000     True
  13       0.16196862       0.16196862    0.000000E+000     True
  14       0.91199124        0.9119913    5.960464E-008     True
  15          1.97384          1.97384    0.000000E+000     True
  16        3.0356889        3.0356886    2.384186E-007     True
  17        4.0095997        4.0095997    0.000000E+000     True
  18        4.9835114         4.983511    4.768372E-007     True
  19        5.9947987         5.994799    4.768372E-007     True
  20         7.006087        7.0060863    4.768372E-007     True
  21         8.001913         8.001913    0.000000E+000     True
  22         8.997738         8.997738    0.000000E+000     True
  23         9.998984         9.998981    2.861023E-006     True
  24        11.000226        11.000226    0.000000E+000     True
  25       12.0001135       12.0001135    0.000000E+000     True
  26               13               13    0.000000E+000     True
  27        13.999999               14    9.536743E-007     True
  28        15.000001        15.000001    0.000000E+000     True
  29        15.999998               16    1.907349E-006     True
  30               17        17.000002    1.907349E-006     True
  31        18.000002               18    1.907349E-006     True

1E-06f 示例:

   index         expected           actual       difference    match
   0   -2.7051452E-34   -2.7051452E-34    0.000000E+000     True
   1    0.00011297482    0.00011297482    0.000000E+000     True
   2    0.00022594964    0.00022594964    0.000000E+000     True
   3    -0.0010179491    -0.0010179491    0.000000E+000     True
   4    -0.0022618477    -0.0022618477    0.000000E+000     True
   5     0.0019123415     0.0019123415    0.000000E+000     True
   6       0.00608653       0.00608653    0.000000E+000     True
   7    -0.0052014478    -0.0052014478    0.000000E+000     True
   8     -0.016489426     -0.016489424    1.862645E-009     True
   9      0.009599558      0.009599558    0.000000E+000     True
  10      0.035688534      0.035688538    3.725290E-009     True
  11     -0.026160091     -0.026160091    0.000000E+000     True
  12      -0.08800873      -0.08800873    0.000000E+000     True
  13       0.16196862       0.16196862    0.000000E+000     True
  14       0.91199124        0.9119913    5.960464E-008     True
  15          1.97384          1.97384    0.000000E+000     True
  16        3.0356889        3.0356886    2.384186E-007     True
  17        4.0095997        4.0095997    0.000000E+000     True
  18        4.9835114         4.983511    4.768372E-007     True
  19        5.9947987         5.994799    4.768372E-007     True
  20         7.006087        7.0060863    4.768372E-007     True
  21         8.001913         8.001913    0.000000E+000     True
  22         8.997738         8.997738    0.000000E+000     True
  23         9.998984         9.998981    2.861023E-006    False
  24        11.000226        11.000226    0.000000E+000     True
  25       12.0001135       12.0001135    0.000000E+000     True
  26               13               13    0.000000E+000     True
  27        13.999999               14    9.536743E-007     True
  28        15.000001        15.000001    0.000000E+000     True
  29        15.999998               16    1.907349E-006    False
  30               17        17.000002    1.907349E-006    False
  31        18.000002               18    1.907349E-006    False

这就是我进行比较的方式:

const float delta = 1E-05f;

var expectedValue = expected[i];
var actualValue   = actual[i];
var difference    = Math.Abs(expectedValue - actualValue);
var failed        = difference > delta;

根据文档,精度约为6到9位。

问题:

我可以比较的最低增量确实是

1E-05f
还是可能
1E-06f

c# floating-point precision
2个回答
0
投票

如果您确定值完全相同,则可以精确比较浮点数。但一旦你开始涉及数学,事情就会变得更加复杂,因为精度将取决于你正在执行的具体操作以及值的范围。

举个例子

(a * b) / a
。结果应该是
b
,但是错误是什么呢?如果
a = float.MaxValue
b = float.MinValue
结果是无穷大,因此误差是无穷大。一般来说,在幅度差异较大的值之间进行运算时,精度会受到影响。

更多详细信息,请参阅我应该如何进行浮点比较?。另请参阅每个程序员应该了解的浮点运算知识

在实践中,对于单元测试,您可以使用通过测试的最低增量。这样你至少知道结果不会变得更糟。如果您需要更高的精度,您可能应该使用 double 来代替。


0
投票

您应该标准化增量,只需看看(夸张的)示例:

expected : 1e-33 
  actual : 1e-30    
   delta : 9.99e-31
 comment : actual is 1000 times larger than expected but stills fit your criterium

expected : 1e+33 
  actual : 1.000000000000001e+33    
   delta : 1e+18
 comment : The difference is tiny (in 15th digit!) but delta doesn't fit your criterium

我认为你应该选择一个不同的选项,比如说

实际至少有 k 个正确数字

int digits = 6;

bool fits = Math.Abs((expected - actual) / actual) < Math.Pow(10, digits);
© www.soinside.com 2019 - 2024. All rights reserved.