4

我编写了一个使用查找表的正弦函数的基本定点变体(针对不带 FPU 的 AVR 微控制器)。我的实现也接受负值和超过 2π 的值,就像它在math.h中的浮点挂件一样。

所以我需要将给定值映射到 0 到 2π 之间的范围(即它们的固定点对应物)。对于积极的论点,很容易用 C 的内置余数运算符%来修剪它们。由于这不是负值的选项,因此我使用以下(明显)方法:

    unsigned int modulus = (a - (INT_FLOOR(a / b) * b) + b) % b;

ab是整数类型的值,而 INT_FLOOR() 只是暗示 (a/b) 的小数部分被截断。该公式确保计算出的模数(用作表格数组的索引)始终为正,并且负参数也映射到它们的正对应物(保持两个方向的相移)。

我对这种方法的问题是它似乎过于复杂,因为它涉及不少于五个算术运算。我缺少更有效的方法吗?

4

2 回答 2

4

除非你的整数参数已经被缩放,使得它们是 π 的倍数(例如 65536 表示 2π),否则尝试进行参数缩减可能是错误的,因为 2π 是不合理的,并且任何缩减 mod 2π 都会引入按比例放大的错误整个归约结果变为错误之前的周期数。这实际上是许多浮点三角实现中的一个严重问题。

我建议要么根本不减少参数,要么使用基于 2 的幂而不是弧度的角度比例(例如,0x10000 或 0x1000000 对应于 2π 或 360 度)。然后参数归约变为单个按位与运算。

于 2012-05-03T23:32:02.777 回答
0

我看到你的公式是正确的,虽然不是那么漂亮。

如果你b是 2 的幂,那么一些操作可以用位掩码来完成。类似于以下内容:

unsigned int modulus = (a - (a & ~(b-1)) + b) & (b-1);

如果b是常量或宏,它应该会优化很多。

于 2012-05-03T22:45:15.013 回答