开发者

qFastSin and qFastCos (Speed, safety and precision)

开发者 https://www.devze.com 2023-04-12 09:51 出处:网络
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:

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_TABL开发者_运维技巧E_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)


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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消