定點化的基本原理

CPU有三種可能的浮點數處理方式

  • Use float instructions if your CPU has a FPU. (fast)
  • Have your compiler translate floating point arithmetic to integer arithmetic. (slow)
  • Use float instructions and a CPU with no FPU. Your CPU will generate a exception (Reserved Instruction, Unimplemented Instruction or similar), and if your OS kernel includes a floating point emulator it will emulate those instructions (slowest).

那麼如果沒有FPU,最好將算法轉移成定點來處理來提高速度,比如:

  • 用整數來模擬浮點數

其實就是線性的映射,根據數據的動態範圍把浮點映射到int8, int16或int32,
比如浮點數A,a=max(abs(A)),若要把A映射成-128~127的數,需要:
A_fix = A*(127 / a) ,即A=A_fix *a / 127;
如果B也是同樣的浮點數,那麼
A * B = A_fix* B_fix * a * b / (127 * 127) 就轉化成一個定點運算。
注意A*(127 / a) 這一步會有精度損失,A_fix* B_fix * a * b / (127 * 127)這一步有可能溢出。

  • 用定點小數來模擬浮點數

所謂定點小數,就是小數點固定的小數。可以參考這篇文章 Fixed Point Arithmetic on the ARM。可以用庫libfixmath
這個庫把浮點變換成Q16.16的定點小數來進行計算,並且可以變換回來。

對於Q16.16的數:
static const fix16_t fix16_one = 0x00010000;
static const fix16_t fix16_maximum = 0x7FFFFFFF;
static const fix16_t fix16_minimum = 0x80000000;
最大精度是1.525e-05, cout << fix16_to_float(0x00000001) <

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章