You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

32位浮点数比较的最低delta值:1E-05f还是1E-06f可行?

FIR滤波器卷积单元测试精度问题

背景

我有一套包含240个针对不同抽头数FIR滤波器卷积的单元测试,用于Unity音频滤波器开发——最初的托管代码朴素卷积速度太慢,无法满足实时音频处理需求。这些测试用来验证不同向量化FIR卷积算法的准确性,最终会选一种用Unity Burst转成支持SIMD的原生代码。

我实现的算法包括:

  • 朴素卷积:用作基准对比
  • 向量化卷积:包含内层、外层、内外层循环版本
  • 上述算法的半带版本:
    • 遍历所有抽头的1抽头/2模式
    • 利用滤波器对称性遍历半数抽头的1抽头/2模式

测试情况

所有测试在delta值为1E-04f时全部通过;降到1E-05f时仍全部通过;但尝试1E-06f时通过率不足50%。

以下是输入信号为0, 1, 2, 3 ... 28, 29, 30, 31时的测试结果:

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;

32位浮点数的精度约为6-9位有效数字。

问题

用于32位浮点数比较的最低delta值是否确实为1E-05f,还是1E-06f仍具备可行性?


回答

首先要明确:32位浮点数的精度是相对精度,不是绝对精度——它的误差范围是基于数值本身的有效位数,而非固定的绝对delta。

从测试结果来看:

  1. 当数值量级在10左右时(比如index23的9.998984),误差达到了2.86e-6,这已经超过了1E-06f的阈值,但仍在32位浮点数的合理精度范围内:10左右的数,6位有效数字对应的绝对误差约为1e-5(10 * 1e-6),7位有效数字对应1e-6。而卷积运算涉及大量加法和乘法,误差会累积,最终超过1e-6是完全正常的。

  2. 1E-05f是更稳妥的选择:它适配了32位浮点数在大部分音频信号量级下的精度表现,且所有测试都能通过。而1E-06f会因为浮点运算的累积误差导致大量测试失败,这并非算法实现错误,而是浮点精度的固有特性。

  3. 如果你想尝试更严格的阈值,不要用固定绝对delta,改用相对误差比较会更合理,比如:

    const float relativeEpsilon = 1E-6f;
    float maxValue = Math.Max(Math.Abs(expectedValue), Math.Abs(actualValue));
    bool failed = difference > maxValue * relativeEpsilon || difference > 1E-7f; // 加最小绝对阈值处理接近0的数
    

    这种方式会根据数值大小动态调整误差允许范围,对小数值更严格,对大数值更宽容,更符合浮点精度的特性。但即使如此,在卷积这种多步运算后,相对误差超过1e-6的情况依然可能存在,需要结合实际音频需求判断——音频信号对微小的浮点误差完全不敏感,只要误差远低于人耳可察觉的阈值(一般是1e-4量级),就不会有问题。

总结:1E-05f是更实际、稳妥的选择;1E-06f在纯理论场景下对小数值可行,但对于卷积这种累积误差的运算,会导致大量不必要的测试失败,不建议使用。


内容的提问来源于stack exchange,提问作者aybe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 13:09:50