pulse[i]
和triosc[i]
中的固定點值是帶符號數量,單位爲2 -31。數學值爲pulse [i]/2 and triosc [i]/2。雖然你可以,只要你不溢出添加這些值,乘以他們需要通過2 調整。這是與pulse[i] * (triosc[i] * 0.0000000004656f))
約完成,但要注意,浮點值不夠精確,它會更精確的寫pulse[i] * (triosc[i]/2147483648.F)
,但結果仍然會失去精度,由於只有23 matissa的比特float
表示。
在執行整數運算的乘法與一個64位的中間步驟實際上是更精確的。
這是可以做到這樣:
((uint64_t)pulse[i] * triosc[i]) >> 31
或等價:
((long long)pulse[i] * triosc[i]) >> 31
編輯
你真的應該使用類型從<stdint.h>
以避免對大小假設long
。它是你當前的系統在32位,但它可能是64上的下一個硬件。這裏是你如何可以重寫表達式:但是
int32_t saw_x2[SIZE];
int32_t pulse[SIZE];
int32_t triosc[SIZE];
int32_t triangle2[SIZE];
int32_t sine_osc[SIZE];
...
saw_x2[i] = (int32_t)(((int64_t)pulse[i] * triosc[i]) >> 31);
int64_t temp = ((int64_t)triangle2[i] * saw_x2[i]) >> 31;
sine_osc[i] = (int32_t)(((temp * pulse[i]) >> 31) << 2);
return sine_osc[i];
注意,如果其中的任何值變爲負值,右移位不能保證產生正確的結果。通過2147483648
分割將是所要求的方法,但可能會產生低效率的代碼:
saw_x2[i] = (int32_t)((int64_t)pulse[i] * triosc[i]/2147483648);
int64_t temp = (int64_t)triangle2[i] * saw_x2[i]/2147483648;
sine_osc[i] = (int32_t)((temp * pulse[i]/2147483648) << 2);
return sine_osc[i];
另外,由於你通過4在最後一步繁殖,則可以通過將由2 代替分割得到的精度2以上位:
sine_osc[i] = (int32_t)(temp * pulse[i]/536870912);
您是否在尋找「是/否」的答案? – usr2564301
由於'2147483648'在十六進制中是'8000000',你只需保留這個符號,那實際上是你想要的嗎? – fvu
看看**部門之後的代碼**,瞭解部門完成的原因以及劃分的值如何使用。像往常一樣,我們可以給你提供的信息非常有限的唯一答案是「可能」和「它取決於」... – fvu