為了節省sin呼叫性能,并處理更便于操作和保存的整數角度,而不是將浮點數作為角度,我正在構建一個sin查找函式,其中 4096 單位等于 2pi 弧度。為了節省記憶體,我只存盤了前 1024 個 sin 值,相當于sin( [0, pi/2) ).
static const float SinTable[1024] = {0, 0.00153398, ..., 0.999995, 0.999999};
為了處理第三和第四象限的角度,我只是有條件地否定:
return Angle&2048 ? -UnsignedSin : UnsignedSin;
UnsignedSin查找的 sin 值在[0, 2048). 但是我該如何處理第二象限和第四象限呢?如何通過檢查角度是否在第二或第四象限(例如 with )[0, 1)來有條件地將存盤的 sin 值映射到?我試過了,但這不太正確,因為角度的結果是 0.999999 而不是應該的 1。[1, 0)Angle&10241024
const float UnsignedSin = SinTable[(Angle&1024 ? ~A : A)&1023];
1 的值永遠不會存盤在 sin 表中,所以我假設 a1-SinTable[...]是必需的?但我不能完全正確。
uj5u.com熱心網友回復:
這就像:
float getSine(unsigned int angle) {
angle &= 4095; // Reduce angle to the range of 1 circle
if( (angle & 2048) == 0) {
if( (angle & 1024) == 0) {
// Angle is from 0 to 1023
return SinTable[angle];
} else {
// Angle is from 1024 to 2047
return SinTable[2048-angle];
}
} else {
if( (angle & 1024) == 0) {
// Angle is from 2048 to 3071
return -SinTable[angle-2048];
} else {
// Angle is from 3072 to 4095
return -SinTable[4096-angle];
}
}
請注意,此代碼SinTable需要 1025 個條目,因此SinTable[1024]有效且包含值 1.0。僅當原始角度為 1024 或 3072(其中SinTable[2048-1024];或SinTable[4096-3072]; 變為SinTable[1024];)時才會發生這種情況。這些角度可以作為特殊情況處理(如if( (angle == 1024) || (angle == 3072) ) return 1.0;),但這可能會更慢(由于分支錯誤預測等)。
另請注意,可以通過使用線性插值來提高精度。例如,您可以說這angle是 20 位,范圍從 0 到 1048575;然后使用位 8 到 19 作為表中的索引(如SinTable[angle >> 8])來確定較低的值和下一個值;然后做int factions = angle & 0xFF; result = ( lower_value * (0x100 - factions) upper * fractions ) / 0x100;一個估計。
uj5u.com熱心網友回復:
我建議您避免位操作,因為將來您可以將 float 更改為 double。我提出了一個更便攜的Brendan answer版本
`define PI_ADDR 2048
float getSine(unsigned int angle) {
angle = angle % (2*PI_ADDR); // Reduce angle to the range of 1 circle
if( angle < PI_ADDR/2) {
return SinTable[angle];
} else if( angle < PI_ADDR) {
return SinTable[PI_ADDR - angle];
} else if( angle < (PI_ADDR*3/2) ) {
return -SinTable[angle-PI_ADDR];
} else {
return -SinTable[2*PI_ADDR -angle];
}
}
關于處理負角,也要便攜:
return (Angle < 0) ? -UnsignedSin : UnsignedSin;
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/431184.html
上一篇:如何在字符陣列中附加部分字串?
下一篇:如何將字串作為宏傳遞?
