qFastSin和qFastCos(速度,安全性和精度)

qFastSin and qFastCos (Speed, safety and precision)

本文关键字:安全性 精度 速度 qFastCos qFastSin      更新时间:2023-10-16

最近我在qmath.h中发现了两个数学函数qFastSinqFastCos。这些函数是inline,并使用查找表来计算sin和cos的值:

inline qreal qFastSin(qreal x)
{
    // Calculating si would be more accurate with qRound, but slower.
    int si = int(x * (0.5 * QT_SINE_TABLE_SIZE / M_PI)); 
    qreal d = x - si * (2.0 * M_PI / QT_SINE_TABLE_SIZE);
    int ci = si + QT_SINE_TABLE_SIZE / 4;
    si &= QT_SINE_TABLE_SIZE - 1;
    ci &= QT_SINE_TABLE_SIZE - 1;
    return qt_sine_table[si] + (qt_sine_table[ci] - 0.5 * qt_sine_table[si] * d) * d;
}
inline qreal qFastCos(qreal x)
{
    // Calculating ci would be more accurate with qRound, but slower.
    int ci = int(x * (0.5 * QT_SINE_TABLE_SIZE / M_PI)); 
    qreal d = x - ci * (2.0 * M_PI / QT_SINE_TABLE_SIZE);
    int si = ci + QT_SINE_TABLE_SIZE / 4;
    si &= QT_SINE_TABLE_SIZE - 1;
    ci &= QT_SINE_TABLE_SIZE - 1;
    return qt_sine_table[si] - (qt_sine_table[ci] + 0.5 * qt_sine_table[si] * d) * d;
}

我搜索了Google和Qt-Assistant,但是没有好的文档。

有人知道这些函数的精度和性能吗?(特别是精密)

它们不是公共API的一部分,不受支持,没有文档,并且可能会更改。

Qt只记录它所支持的,它只支持它所记录的。这样很好。

它看起来像一个简单的线性插值,因此精度取决于QT_SINE_TABLE_SIZE以及输入恰好与样本点的接近程度。最坏的情况是1-sin(pi/2 + 2*pi*(QT_SINE_TABLE_SIZE/2))

如果你更关心性能而不是准确性,那么你可以在实践中使用它们,但理论上它们可能会在将来被完全删除

我使用随机值和数百万次迭代进行测试,与std::sin/cos相比,我得到的最大误差约为0.00000246408。