許多MCU 芯片只支持整數(shù)運算,如果要在這些芯片上進行小數(shù)運算,定點運算應(yīng)該是最佳選擇了;此外即使芯片支持浮點數(shù),定點小數(shù)運算也是最佳的速度選擇。所謂定點小數(shù)運算,就是將小數(shù)點位置固定,用整數(shù)的方式來進行運算;由于小數(shù)點的位置是固定的,所以就沒有必要儲存它。既然沒有儲存小數(shù)點的位置,那么計算機當(dāng)然就不知道小數(shù)點的位置,所以這個小數(shù)點的位置是我們寫程序的人自己需要牢記的。那么,如何將小數(shù)表示成整數(shù)呢?
處理器整數(shù)以二進制形式存儲,首先要了解如何將小數(shù)轉(zhuǎn)換成二進制!假定MCU 是16位,因最高位是符號位,那么有效位就只有15位(不考慮符號則16位)。即小數(shù)點之后可以有0~15 位。我們把小數(shù)點之后有n位叫做Qn,例如小數(shù)點之后有12位叫做Q12 格式的定點小數(shù),而Q0就是我們所說的整數(shù):

以Q12 格式為例,Q12 的正數(shù)的最大值是0111.111111111111,第一個0是符號位,后面的數(shù)都是1,那么這個數(shù)是十進制的多少呢? 請看下面的運算:



對于Qn格式的定點小數(shù)的表達的數(shù)值就它的整數(shù)值除以2^Qn。在計算機中還是以整數(shù)來運算,我們把它想象成實際所表達的值的時候,進行這個運算。反過來把一個實際所要表達的值x 轉(zhuǎn)換Qn 型的定點小數(shù)的時候,就是x*(2^ Qn)了。例如0.2 的Q12 型定點小數(shù)為:0.2*(2^12) =819.2,由于這個數(shù)要用整數(shù)儲存, 所以是819 即0x0333。因為舍棄了小數(shù)部分,所以0x0333 不是精確的0.2,實際上它是819/2^12=0.199951171875,非常接近0.2 了。
因此我們可以歸納出一個公式,假定x 表示實際的小數(shù), q表示這小數(shù)在MCU 中的Qn 型定點小數(shù),則有:

由以上公式我們可以很快得出定點小數(shù)運算法則:

加減法和一般的整數(shù)運算相同,而乘除法的時候,為了使得結(jié)果的小數(shù)點位不移動,對數(shù)值進行了移動(乘除2^Qn實際是將被乘除數(shù)左或右移動n位):
q3 = q1 * q2 / (2^Qn) ---> q3 = (q1 * q2 )>>Qn
用c語言來寫定點小數(shù)的乘法就是:
short q1,q2,q3;
....
q3=((long q1) * (long q2)) >> n;
由于/ 2^Qn 和* 2^Qn可以簡單的用移位來計算,所以定點小數(shù)的運算比浮點小數(shù)要快得多。下面我們用一個例子來驗證一下上面的公式:用Q12來計算2.1 * 2.2,先把2.1, 2.2轉(zhuǎn)換為Q12 定點小數(shù):
2.1 * 2^12 = 8601.6 = 8602
2.2 * 2^12 = 9011.2 = 9011
(8602 * 9011) >> 12 = 18923
18923 的實際值是18923/(2^12) = 4.619873046875 和實際的結(jié)果4.62相差0.000126953125,對于一般的計算已經(jīng)足夠精確了。好了,話不投機半句多,說了這么多,最終還是要用實例代碼來形象的指出如何實現(xiàn)定點運算。
MCU 實例
用碩呈16BIT-MCU 實現(xiàn)一組數(shù)據(jù)乘以0.492,這組數(shù)據(jù)是:
100*0.492=49.2
105*0.492=51.66
147*0.492=72.324
350*0.492=172.2
860*0.492=423.12
458*0.492=225.336
步驟一,先確定小數(shù),0.492屬于小于“1”的小數(shù);且乘數(shù)與被乘數(shù)符號都為正,為了提高精度,可以考慮使用Q16 格式;因此將0.492轉(zhuǎn)換成定點小數(shù)有:

步驟二,編寫如下代碼:


在地址0x00F0 處,設(shè)定運算為無符號乘以無符號運算。
地址0x00F1 處,將Q16 小數(shù)送入MX 寄存器。
地址0x00f4~0x00f8 處,利用循環(huán)計算出_MUL_表格中列出的數(shù)據(jù),并將結(jié)果存到I0指向的緩沖中(MR1 是計算結(jié)果的整數(shù)位,MR0 是計算結(jié)果的小數(shù)低位)。
計算結(jié)果請查閱以下表格:

如果運算不需要小數(shù)部分(即運算結(jié)果取整),則"MCU 運算結(jié)果"中的數(shù)值均需要向右移動16位去掉小數(shù)部分;在代碼中,用戶可以直接取MR1的數(shù)字做為整數(shù)結(jié)果(假如不考慮四舍五入)。
-
mcu
+關(guān)注
關(guān)注
147文章
18934瀏覽量
398530 -
FOC
+關(guān)注
關(guān)注
21文章
389瀏覽量
46228
原文標(biāo)題:一步步解剖FOC之定點小數(shù)運算!
文章出處:【微信號:fcsde-sh,微信公眾號:fcsde-sh】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
定點小數(shù)運算
定點數(shù)表示實數(shù)的方法以及定點數(shù)在硬件上的運算驗證
基于牛頓迭代法的FPGA定點小數(shù)計算
【每日一知識點】如何在沒有浮點運算的單片機中,更高效快速的進行小數(shù)運算?
定點小數(shù)的表示方法
定點小數(shù)的編碼方法
定點DSP,定點DSP是什么意思
一文了解FPGA浮點小數(shù)與定點小數(shù)的換算及應(yīng)用
DSP基礎(chǔ)知識集錦之DSP芯片的定點運算
LM4F定點格式于浮點格式的對比和浮點運算的應(yīng)用詳細(xì)中文資料
FPGA定點小數(shù)的常規(guī)格式、相對于浮點小數(shù)的優(yōu)勢與劣勢和計算的概述
FOC之定點小數(shù)運算
評論