qFastSin和qFastCos(速度,安全性和精度)
qFastSin and qFastCos (Speed, safety and precision)
最近我在qmath.h
中发现了两个数学函数qFastSin
和qFastCos
。这些函数是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。
相关文章:
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 如何防止 c++ 在从浮点型转换为双精度型(不适用于 IO)时添加额外的小数?
- 正在将csv文件读取为双精度矢量
- 如何理解将半精度指针转换为无符号长指针和相关的内存对齐
- 类与私有变量的其他类之间的线程安全性
- 我可以信任表示整数的浮点或双精度来保持精度吗
- 如何在C++中的同一函数中使用字符串和双精度
- 特征::矩阵<双精度,1,3> 结构类型函数中的返回类型函数
- 当使用比格式支持的精度更高的精度来显示数字时,会写出什么数据
- 如何计算具有指定类型的表达式的相对精度和绝对精度
- 如何打印boost多精度128位无符号整数
- 检查是否以特定精度给出双精度
- 转换函数,将 std::数组的双精度作为参数或双精度作为参数单独转换
- C 字符串返回字符串的整数/双精度/长整型值
- 是否值得降低我的代码的可读性,以便在出现内存不足错误时提供异常安全性?
- 为什么将双精度转换为 int 似乎在第 16 位数字之后将其四舍五入?
- 如何使双精度值的 C++ 和 C# 中的结果相同
- 使用浮点数和双精度数的非常小数字的数学
- 使用 Xcode 将双精度存储在数组C++中
- qFastSin和qFastCos(速度,安全性和精度)