許多MCU 芯片只支持整數(shù)運(yùn)算,如果要在這些芯片上進(jìn)行小數(shù)運(yùn)算,定點(diǎn)運(yùn)算應(yīng)該是最佳選擇了;此外即使芯片支持浮點(diǎn)數(shù),定點(diǎn)小數(shù)運(yùn)算也是最佳的速度選擇。所謂定點(diǎn)小數(shù)運(yùn)算,就是將小數(shù)點(diǎn)位置固定,用整數(shù)的方式來進(jìn)行運(yùn)算;由于小數(shù)點(diǎn)的位置是固定的,所以就沒有必要儲(chǔ)存它。既然沒有儲(chǔ)存小數(shù)點(diǎn)的位置,那么計(jì)算機(jī)當(dāng)然就不知道小數(shù)點(diǎn)的位置,所以這個(gè)小數(shù)點(diǎn)的位置是我們寫程序的人自己需要牢記的。那么,如何將小數(shù)表示成整數(shù)呢?
處理器整數(shù)以二進(jìn)制形式存儲(chǔ),首先要了解如何將小數(shù)轉(zhuǎn)換成二進(jìn)制!假定MCU 是16位,因最高位是符號(hào)位,那么有效位就只有15位(不考慮符號(hào)則16位)。即小數(shù)點(diǎn)之后可以有0~15 位。我們把小數(shù)點(diǎn)之后有n位叫做Qn,例如小數(shù)點(diǎn)之后有12位叫做Q12 格式的定點(diǎn)小數(shù),而Q0就是我們所說的整數(shù):
以Q12 格式為例,Q12 的正數(shù)的最大值是0111.111111111111,第一個(gè)0是符號(hào)位,后面的數(shù)都是1,那么這個(gè)數(shù)是十進(jìn)制的多少呢? 請(qǐng)看下面的運(yùn)算:
對(duì)于Qn格式的定點(diǎn)小數(shù)的表達(dá)的數(shù)值就它的整數(shù)值除以2^Qn。在計(jì)算機(jī)中還是以整數(shù)來運(yùn)算,我們把它想象成實(shí)際所表達(dá)的值的時(shí)候,進(jìn)行這個(gè)運(yùn)算。反過來把一個(gè)實(shí)際所要表達(dá)的值x 轉(zhuǎn)換Qn 型的定點(diǎn)小數(shù)的時(shí)候,就是x*(2^ Qn)了。例如0.2 的Q12 型定點(diǎn)小數(shù)為:0.2*(2^12) =819.2,由于這個(gè)數(shù)要用整數(shù)儲(chǔ)存, 所以是819 即0x0333。因?yàn)樯釛壛诵?shù)部分,所以0x0333 不是精確的0.2,實(shí)際上它是819/2^12=0.199951171875,非常接近0.2 了。
因此我們可以歸納出一個(gè)公式,假定x 表示實(shí)際的小數(shù), q表示這小數(shù)在MCU 中的Qn 型定點(diǎn)小數(shù),則有:
由以上公式我們可以很快得出定點(diǎn)小數(shù)運(yùn)算法則:
加減法和一般的整數(shù)運(yùn)算相同,而乘除法的時(shí)候,為了使得結(jié)果的小數(shù)點(diǎn)位不移動(dòng),對(duì)數(shù)值進(jìn)行了移動(dòng)(乘除2^Qn實(shí)際是將被乘除數(shù)左或右移動(dòng)n位):
q3 = q1 * q2 / (2^Qn) ---> q3 = (q1 * q2 )>>Qn
用c語言來寫定點(diǎn)小數(shù)的乘法就是:
short q1,q2,q3;
....
q3=((long q1) * (long q2)) >> n;
由于/ 2^Qn 和* 2^Qn可以簡(jiǎn)單的用移位來計(jì)算,所以定點(diǎn)小數(shù)的運(yùn)算比浮點(diǎn)小數(shù)要快得多。下面我們用一個(gè)例子來驗(yàn)證一下上面的公式:用Q12來計(jì)算2.1 * 2.2,先把2.1, 2.2轉(zhuǎn)換為Q12 定點(diǎn)小數(shù):
2.1 * 2^12 = 8601.6 = 8602
2.2 * 2^12 = 9011.2 = 9011
(8602 * 9011) >> 12 = 18923
18923 的實(shí)際值是18923/(2^12) = 4.619873046875 和實(shí)際的結(jié)果4.62相差0.000126953125,對(duì)于一般的計(jì)算已經(jīng)足夠精確了。好了,話不投機(jī)半句多,說了這么多,最終還是要用實(shí)例代碼來形象的指出如何實(shí)現(xiàn)定點(diǎn)運(yùn)算。
MCU 實(shí)例
用碩呈16BIT-MCU 實(shí)現(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ù)符號(hào)都為正,為了提高精度,可以考慮使用Q16 格式;因此將0.492轉(zhuǎn)換成定點(diǎn)小數(shù)有:
步驟二,編寫如下代碼:
在地址0x00F0 處,設(shè)定運(yùn)算為無符號(hào)乘以無符號(hào)運(yùn)算。
地址0x00F1 處,將Q16 小數(shù)送入MX 寄存器。
地址0x00f4~0x00f8 處,利用循環(huán)計(jì)算出_MUL_表格中列出的數(shù)據(jù),并將結(jié)果存到I0指向的緩沖中(MR1 是計(jì)算結(jié)果的整數(shù)位,MR0 是計(jì)算結(jié)果的小數(shù)低位)。
計(jì)算結(jié)果請(qǐng)查閱以下表格:
如果運(yùn)算不需要小數(shù)部分(即運(yùn)算結(jié)果取整),則"MCU 運(yùn)算結(jié)果"中的數(shù)值均需要向右移動(dòng)16位去掉小數(shù)部分;在代碼中,用戶可以直接取MR1的數(shù)字做為整數(shù)結(jié)果(假如不考慮四舍五入)。
-
mcu
+關(guān)注
關(guān)注
146文章
17984瀏覽量
367023 -
FOC
+關(guān)注
關(guān)注
21文章
347瀏覽量
44317
原文標(biāo)題:一步步解剖FOC之定點(diǎn)小數(shù)運(yùn)算!
文章出處:【微信號(hào):fcsde-sh,微信公眾號(hào):fcsde-sh】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
基于牛頓迭代法的FPGA定點(diǎn)小數(shù)計(jì)算
【每日一知識(shí)點(diǎn)】如何在沒有浮點(diǎn)運(yùn)算的單片機(jī)中,更高效快速的進(jìn)行小數(shù)運(yùn)算?
DSP芯片的定點(diǎn)運(yùn)算
定點(diǎn)小數(shù)的表示方法
定點(diǎn)小數(shù)的編碼方法

定點(diǎn)DSP,定點(diǎn)DSP是什么意思
Labview之字符轉(zhuǎn)小數(shù)
DSP芯片的定點(diǎn)運(yùn)算
一文了解FPGA浮點(diǎn)小數(shù)與定點(diǎn)小數(shù)的換算及應(yīng)用
DSP基礎(chǔ)知識(shí)集錦之DSP芯片的定點(diǎn)運(yùn)算
DSP第6章 DSP芯片的定點(diǎn)運(yùn)算
LM4F定點(diǎn)格式于浮點(diǎn)格式的對(duì)比和浮點(diǎn)運(yùn)算的應(yīng)用詳細(xì)中文資料

FPGA定點(diǎn)小數(shù)的常規(guī)格式、相對(duì)于浮點(diǎn)小數(shù)的優(yōu)勢(shì)與劣勢(shì)和計(jì)算的概述

評(píng)論