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

发布于 2024-12-09 18:26:11 字数 1110 浏览 0 评论 0原文

最近我在qmath.h中发现了两个数学函数,名为qFastSinqFastCos。这些函数是内联的,并使用查找表来计算 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 中搜索了有关它们的信息,但没有好的文档。

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

Recently I found two mathematical functions in qmath.h named qFastSin and qFastCos. These functions are inline and uses look-up tables to calculate the value of sin and 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;
}

I searched Google and Qt-Assistant for information about them, but there is no good documentaion.

Does anybody know about precision and performance of these function? (Specially precision)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

原谅过去的我 2024-12-16 18:26:11

它们不是公共 API 的一部分,不受支持,没有记录,并且可能会发生变化。

Qt 仅记录其支持的内容,并且仅支持其记录的内容 。这样就好了。

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

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

They are not part of the public API, not supported, not documented, and subject to change.

Qt only documents what it supports and it only supports what it documents. It's good like that.

It looks like a simple linear interpolation so accuracy depends on QT_SINE_TABLE_SIZE and also how close to a sample point the input happens to be. The worse case error will then be 1-sin(pi/2 + 2*pi*(QT_SINE_TABLE_SIZE/2))

If you care about performance more than accuracy then you can use them in practice but in theory they may be removed entirely in future.

终弃我 2024-12-16 18:26:11

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

I tested using random values and millions of iterations and the maximum error that I got was ~0.00000246408 compared to std::sin/cos. It also seems to be ~5x faster.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文