如何用 C++ 重写以下伪代码?
real array sine_table[-1000..1000]
for x from -1000 to 1000
sine_table[x] := sine(pi * x / 1000)
我需要创建一个 sine_table 查找表。
最佳答案
您可以通过仅存储第一象限的值(即 [0,pi/2] 中的 x)将表的大小减少到原始的 25%。
为此,您的查找例程只需使用简单的三角标识将 x 的所有值映射到第一象限:
- sin(x) = - sin(-x),从象限 IV 映射到 I
- sin(x) = sin(pi - x),从象限 II 映射到 I
要从象限 III 映射到 I,应用两个恒等式,即 sin(x) = - sin (pi + x)
此策略是否有帮助取决于您的情况有多少内存使用量。但是为了避免在查找过程中进行一两次比较和减法,存储四倍于您所需的值似乎很浪费。
我赞同 Jeremy 的建议,即衡量构建表是否比仅使用 std::sin() 更好。即使使用原始的大表,您也必须在每次查找表期间花费循环来将参数转换为最接近的 pi/1000 增量,并且您会在此过程中失去一些准确性。
如果您真的想以准确性换取速度,您可以尝试仅使用泰勒级数展开式的前几项来逼近 sin() 函数。
- sin(x) = x - x^3/3! + x^5/5! ...,其中 ^ 表示提升到幂和 !代表阶乘。
当然,为了提高效率,您应该预先计算阶乘并利用 x 的较低幂来计算较高的幂,例如计算 x^5 时使用 x^3。
最后一点,上面截断的泰勒级数对于接近零的值更准确,因此在计算近似正弦之前映射到第一或第四象限仍然值得。
附录:
基于以下两个观察结果的另一项潜在改进:
1. 如果您可以计算第一个八分圆 [0,pi/4] 中的正弦和余弦,则可以计算任何三角函数
2. 以零为中心的泰勒级数展开在零附近更准确
因此,如果您决定使用截断的泰勒级数,则可以通过映射到正弦或余弦来提高准确度(或使用更少的项来获得相似的准确度)以获得 [0,pi/4] 范围内的角度除了上面的那些(例如,如果 x > pi/4 一旦你已经映射到第一象限。)
或者,如果您决定对正弦和余弦都使用表查找,则可以使用仅覆盖范围 [0,pi/4] 的两个较小的表来解决问题,而代价是查找时可能会进行另一个可能的比较和减法映射到较小的范围。然后,您可以为表使用更少的内存,或者使用相同的内存但提供更精细的粒度和准确性。
关于c++ - 在 C++ 中创建正弦查找表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3688649/