[英]How to efficiently calculate a modulus in C by hand?
我寫了一個正弦函數的基本定點變體,它利用了一個查找表(針對沒有FPU的AVR微控制器)。 我的實現也接受負值和超過2π的值,就像math.h中的浮點鏈接一樣。
所以我需要將給定值映射到0到2π之間的范圍(即它們的固定點對應物)。 對於正面參數,可以使用C的內置余數運算符%來修剪它們。 由於這不是負值的選項,我使用以下(顯而易見的)方法:
unsigned int modulus = (a - (INT_FLOOR(a / b) * b) + b) % b;
a和b是整數類型值,INT_FLOOR()僅表示(a / b)的小數部分被截斷的提示。 此公式確保計算的模數(用作表數組的索引)始終為正,並且負參數也映射為正對應(保持兩個方向的相移)。
我對這種方法的問題在於它似乎過於復雜,因為它涉及不少於五次算術運算。 我缺少一種更有效的方法嗎?
除非你的整數參數已被縮放,使得它們以π的倍數表示(例如65536表示2π),嘗試減少參數可能是錯誤的,因為2π是不合理的,任何減少mod2π都會引入錯誤,直到整個減少結果變為錯誤的周期數。 這實際上是許多浮點觸發器實現中的一個嚴重問題。
我建議要么根本不做減少參數,要么使用基於2的冪而不是弧度的角度刻度(例如,0x10000或0x1000000對應2π或360度)。 然后參數減少變為單個按位和操作。
我看到你的公式是正確的,雖然不那么漂亮。
如果使b
為2的冪,則可以使用位掩碼執行某些操作。 有點像:
unsigned int modulus = (a - (a & ~(b-1)) + b) & (b-1);
如果b
是常數或宏,它應該優化很多。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.