新聞中心

EEPW首頁(yè) > 汽車(chē)電子 > DSP基礎(chǔ)--定點(diǎn)小數(shù)運(yùn)算

DSP基礎(chǔ)--定點(diǎn)小數(shù)運(yùn)算

——
作者: 時(shí)間:2006-12-13 來(lái)源: 收藏
許多芯片只支持整數(shù)運(yùn)算,如果現(xiàn)在這些芯片上進(jìn)行小數(shù)運(yùn)算的話,定點(diǎn)小數(shù)運(yùn)算應(yīng)該是最佳選擇了,此外即使芯片支持浮點(diǎn)數(shù),定點(diǎn)小數(shù)運(yùn)算也是最佳的速度選擇。

        在世界中,由于芯片的限制,經(jīng)常使用定點(diǎn)小數(shù)運(yùn)算。所謂定點(diǎn)小數(shù),實(shí)際上就是用整數(shù)來(lái)進(jìn)行小數(shù)運(yùn)算。下面先介紹定點(diǎn)小數(shù)的一些理論知識(shí),然后以C語(yǔ)言為例,介紹一下定點(diǎn)小數(shù)運(yùn)算的方法。在TI C5000 DSP系列中使用16比特為最小的儲(chǔ)存單位,所以我們就用16比特的整數(shù)來(lái)進(jìn)行定點(diǎn)小數(shù)運(yùn)算。

        先從整數(shù)開(kāi)始,16比特的儲(chǔ)存單位最多可以表示0x0000到0xffff,65536種狀態(tài),如果它表示C語(yǔ)言中的無(wú)符號(hào)整數(shù)的話,就是從0到65535。如果需要表示負(fù)數(shù)的話,那么最高位就是符號(hào)位,而剩下的15位可以表示32768種狀態(tài)。這里可以看出,對(duì)于計(jì)算機(jī)或者DSP芯片來(lái)說(shuō),符號(hào)并沒(méi)有什么特殊的儲(chǔ)存方式,其實(shí)是和數(shù)字一起儲(chǔ)存的。為了使得無(wú)論是無(wú)符號(hào)數(shù)還是符號(hào)數(shù),都可以使用同樣的加法減法規(guī)則,符號(hào)數(shù)中的負(fù)數(shù)用正數(shù)的補(bǔ)碼表示。

        我們都知道-1 + 1 =0,而0x0001表示1,那么-1用什么來(lái)表示才能使得-1 + 1 =0呢?答案很簡(jiǎn)單:0xffff。現(xiàn)在就可以打開(kāi)Windows的計(jì)算器,用16進(jìn)制計(jì)算一下0xffff+0x0001,結(jié)果是0x10000。那么0x10000和0x0000等價(jià)麼,我們剛才說(shuō)過(guò)用16比特來(lái)表達(dá)整數(shù),最高位的1是第17位,這一位是溢出位,在運(yùn)算寄存器中沒(méi)有儲(chǔ)存這一位,所以結(jié)果是低16位,也就是0x0000。現(xiàn)在我們知道負(fù)數(shù)的表達(dá)方式了。舉個(gè)例子:-100。首先我們需要知道100的16進(jìn)制,用計(jì)算器轉(zhuǎn)換一下,可以知道是0x0064,那么-100就是0x10000 - 0x0064,用計(jì)算器算一下得0xff9c。還有一種簡(jiǎn)單的轉(zhuǎn)換符號(hào)的方法,就是取反加一:把數(shù)x寫(xiě)成二進(jìn)制格式,每位0變1,1變0,最后把結(jié)果加1就是-x了。

        好,復(fù)習(xí)了整數(shù)的相關(guān)知識(shí)之后,我們進(jìn)入定點(diǎn)小數(shù)運(yùn)算環(huán)節(jié)。所謂定點(diǎn)小數(shù),就是小數(shù)點(diǎn)的位置是固定的。我們是要用整數(shù)來(lái)表示定點(diǎn)小數(shù),由于小數(shù)點(diǎn)的位置是固定的,所以就沒(méi)有必要儲(chǔ)存它(如果儲(chǔ)存了小數(shù)點(diǎn)的位置,那就是浮點(diǎn)數(shù)了)。既然沒(méi)有儲(chǔ)存小數(shù)點(diǎn)的位置,那么計(jì)算機(jī)當(dāng)然就不知道小數(shù)點(diǎn)的位置,所以這個(gè)小數(shù)點(diǎn)的位置是我們寫(xiě)程序的人自己需要牢記的。

         先以10進(jìn)制為例。如果我們能夠計(jì)算12+34=46的話,當(dāng)然也就能夠計(jì)算1.2+3.4 或者 0.12+0.34了。所以定點(diǎn)小數(shù)的加減法和整數(shù)的相同,并且和小數(shù)點(diǎn)的位置無(wú)關(guān)。乘法就不同了。 12*34=408,而1.2*3.4=4.08。這里1.2的小數(shù)點(diǎn)在第1位之前,而4.08的小數(shù)點(diǎn)在第2位之前,小數(shù)點(diǎn)發(fā)生了移動(dòng)。所以在做乘法的時(shí)候,需要對(duì)小數(shù)點(diǎn)的位置進(jìn)行調(diào)整?!可是既然我們是做定點(diǎn)小數(shù)運(yùn)算,那就說(shuō)小數(shù)點(diǎn)的位置不能動(dòng)?。≡趺唇鉀Q這個(gè)矛盾呢,那就是舍棄最低位。 也就說(shuō)1.2*3.4=4.1,這樣我們就得到正確的定點(diǎn)運(yùn)算的結(jié)果了。所以在做定點(diǎn)小數(shù)運(yùn)算的時(shí)候不僅需要牢記小數(shù)點(diǎn)的位置,還需要記住表達(dá)定點(diǎn)小數(shù)的有效位數(shù)。上面這個(gè)例子中,有效位數(shù)為2,小數(shù)點(diǎn)之后有一位。

       現(xiàn)在進(jìn)入二進(jìn)制。我們的定點(diǎn)小數(shù)用16位二進(jìn)制表達(dá),最高位是符號(hào)位,那么有效位就是15位。小數(shù)點(diǎn)之后可以有0 - 15位。我們把小數(shù)點(diǎn)之后有n位叫做Qn,例如小數(shù)點(diǎn)之后有12位叫做Q12格式的定點(diǎn)小數(shù),而Q0就是我們所說(shuō)的整數(shù)。

       Q12的正數(shù)的最大值是 0 111 . 111111111111,第一個(gè)0是符號(hào)位,后面的數(shù)都是1,那么這個(gè)數(shù)是十進(jìn)制的多少呢,很好運(yùn)算,就是 0x7fff / 2^12 = 7.999755859375。對(duì)于Qn格式的定點(diǎn)小數(shù)的表達(dá)的數(shù)值就它的整數(shù)值除以2^n。在計(jì)算機(jī)中還是以整數(shù)來(lái)運(yùn)算,我們把它想象成實(shí)際所表達(dá)的值的時(shí)候,進(jìn)行這個(gè)運(yùn)算。

       反過(guò)來(lái)把一個(gè)實(shí)際所要表達(dá)的值x轉(zhuǎn)換Qn型的定點(diǎn)小數(shù)的時(shí)候,就是x*2^n了。例如 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。

我們用數(shù)學(xué)表達(dá)式做一下總結(jié):
x表示實(shí)際的數(shù)(*一個(gè)浮點(diǎn)數(shù)), q表示它的Qn型定點(diǎn)小數(shù)(一個(gè)整數(shù))。
q = (int) (x * 2^n)
x = (float)q/2^n

由以上公式我們可以很快得出定點(diǎn)小數(shù)的+-*/算法:
假設(shè)q1,q2,q3表達(dá)的值分別為x1,x2,x3
q3 = q1 + q2   若 x3 = x1 + x2
q3 = q1 - q2   若 x3 = x1 - x2
q3 = q1 * q2 / 2^n若 x3 = x1 * x2
q3 = q1 * 2^n / q2若 x3 = x1 / x2
我們看到加減法和一般的整數(shù)運(yùn)算相同,而乘除法的時(shí)候,為了使得結(jié)果的小數(shù)點(diǎn)位不移動(dòng),對(duì)數(shù)值進(jìn)行了移動(dòng)。
用c語(yǔ)言來(lái)寫(xiě)定點(diǎn)小數(shù)的乘法就是:
short q1,q2,q3;
....
q3=((long q1) * (long q2)) >> n;

由于/ 2^n和* 2^n可以簡(jiǎn)單的用移位來(lái)計(jì)算,所以定點(diǎn)小數(shù)的運(yùn)算比浮點(diǎn)小數(shù)要快得多。下面我們用一個(gè)例子來(lái)驗(yàn)證一下上面的公式:
用Q12來(lái)計(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)足夠精確了



關(guān)鍵詞: DSP

評(píng)論


相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉