http://tw.myblog.yahoo.com/ericsu-blog/article?mid=404&prev=431&l=f&fid=7
為了加快在dsPIC中的加減乘除四則運算,我們要花一些時間討論「定點數的四則運算」。
在計算機的數學運算中對比於定點數的數字表示法,且更精確的是浮點數的數字表示法。
這裡要討論的定點數四則運算是指用長整數(long)且小數位數固定的數字表示法,來進行實數的四則運算。
例如2.3*3.8。
根據Wikipedia,常用的定點數表示法是 Qy 或 Qx.y,其中 x 是表示整數部分的位元數,y 則是表示小數部分的位元數。
例如我們使用32位元的有號長整數時,Q12 是表示整數部分使用(31-12)19位元,小數部分則是使用12位元。
Q25.6 是表示整數部分使用 25 位元,小數部分則是使用 6 位元。
以 Q25.6 為例,實數的1就變成 1*2^6 = 64,也就是左移 6 位元的意思。
加法與減法
例1:Q25.6 2.3 + 3.8
2.3 (147 ~ 2.3*2^6 Q25.6) + 3.8(243 ~ 3.8*2^6 Q25.6)
= 147 + 243 ~ (2.3*2^6 + 3.8*2^6) ~ ((2.3+3.8)*2^6)
= 390 (6.09375*2^6) (6.1*2^6 = 390.4)
結論:加減法可以保持相同的表示法解析度,直接將轉移成定點數表示法的長整數相加減即可。
---------------------------------------------
問題1:如果兩個不同定點數表示法的數字要相加時怎麼辦?
例2:(Q25.6)2.3 + (Q26.5)3.8
2.3 (147 ~ 2.3*2^6 Q25.6) + 3.8(121 ~ 3.8*2^5 Q26.5)
= 147 + 121<<1 ~ (2.3*2^6 + 3.8*2^6) ~ ((2.3+3.8)*2^6)
= 147 + 242 = 389 (6.078125*2^6) 解析度調整成較差的表示法
or
= 147>>1 + 121 ~ (2.3*2^5 + 3.8*2^5) ~ ((2.3+3.8)*2^5)
= 73 + 121 = 194 (6.0625*2^5)
這樣的解析度的調整似乎造成更大的誤差。但這其實是跟加完後的變數解析度有關
如果是 (Q26.5) y = (Q25.6)2.3 + (Q26.5)3.8
那麼答案就是 389>>1 = 194 反而一樣。
如果是 (Q25.6) y = (Q25.6)2.3 + (Q26.5)3.8
那麼答案就是 194<<1 = 388 ,第一種調整解析度的方法是比較好的。
結論:相加前先不要犧牲解析度,也就是將解析度差的調整成解析度好的,加完後再調整解析度。
---------------------------------------------------------------------------------
乘法
例3:Q25.6 2.3 * 3.8
2.3 (147 ~ 2.3*2^6 Q25.6) * 3.8(243 ~ 3.8*2^6 Q25.6)
= 147 * 243 ~ ((2.3*2^6 ) * (3.8*2^6)) ~ ((2.3*3.8)*2^6*2^6)
= 35721>>6 (8.74*2^6 = 559.36)
= 558(8.71875*2^6)
結論:乘法會讓結果增加小數部分的位元數,因此需要右移位元數來調整相同的表示法解析度。
問題2:如果兩個不同定點數表示法的數字要相乘時怎麼辦?
例4:(Q25.6) y = (Q25.6)2.3 * (Q26.5)3.8
2.3 (147 ~ 2.3*2^6 Q25.6) * 3.8(121 ~ 3.8*2^5 Q26.5)
= 147*121 >>5 = 17787>>5 = 555 (8.671875*2^6) (8.74*2^6 = 559.36)
結論:右移的位元數要由結果的解析度來調整。
問題3:如果兩個使用 16 位元的有號定點數表示的數字相乘時溢位怎麼辦?
例5:(Q11.4) y = (Q11.4)52.3 * (Q11.4)33.8
52.3*33.8 = 1767.74 還在 Q11.4 的表示範圍(2048.9375~-2048.9375)內,這很重要!
52.3 (836 ~ 52.3*2^4 Q11.4) * 33.8(540 ~ 33.8*2^4 Q11.4)
836*540 = 451440 > 2^15 = 32768 超出16 位元有號數的表示範圍。
作法1:836 = 52*2^4 (52 是 Q11.4 的整數部份) + 4(4 是 Q11.4 的小數部份),
540 = 33*2^4 (33 是 Q11.4 的整數部份) + 12(12 是 Q11.4 的小數部份),
836*540>>4 = 836*(540>>4) + (836*12)>>4 = 27588 + 10032>>4 = 28215
28215 = 1763.4375*2^4 (52.3*33.8 = 1767.74 )。
結論:a*b => (a*(b>>4) (b的整數部份)) + (a*b的小數部份>>4)。
另一篇文章的作法:
http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.89.7808&rep=rep1&type=pdf
a*b = ( (a的小數部份)*(b的小數部份) )>>4 + (a>>4)*b + (a的小數部份)*(b>>4)
= (4*12)>>4 + 52*540 + 4*33 = 28215 是一樣的!
為何是這樣的公式呢?
問題4:如果兩個使用 16 位元的有號定點數,而且定點數表示法不同的數字相乘時溢位怎麼辦?
例6:(Q11.4) y = (Q11.4)52.3 * (Q10.5)33.8
52.3*33.8 = 1767.74 還在 Q11.4 的表示範圍(2048.9375~-2048.9375)內。
52.3 (836 ~ 52.3*2^4 Q11.4) * 33.8(1081 ~ 33.8*2^5 Q10.5)
836*1081 = 903716 > 2^15 = 32768 超出16 位元有號數的表示範圍。
作法: 836 = 52*2^4 (52 是 Q11.4 的整數部份) + 4(4 是 Q11.4 的小數部份),
1081 = 33*2^5 (33 是 Q10.5 的整數部份) + 25(25 是 Q10.5 的小數部份),
a*b => (a*(b>>5) (b的整數部份)) + (a*b的小數部份>>5)。
836*1081>>5(=5+4-4) = 836*(1081>>5) + (836*25)>>5 = 27588 + 20900>>5 = 28241
28241 = 1765.0625*2^4 (52.3*33.8 = 1767.74 )。
---------------------------------------------
除法
跟乘法不一樣的是,除法的被除數要先提昇解析度後再使用整數的除法
EXTRA:
例如,浮点数x=0.5,定标Q=15,则定点数xq=L0.5*32768J=16384,式中LJ表示下取整。反之,一个用Q=15表示的定点数16384,其浮点数为163幼*2-15=16384/32768=0.5。浮点数转换为定点数时,为了降低截尾误差,在取整前可以先加上0.5。
表1.1 Q表示、S表示及数值范围
Q表示 S表示 十进制数表示范围
Q15 S0.15 -1≤x≤0.9999695<--1-(1/2^15)
Q14 S1.14 -2≤x≤1.9999390<--2-(1/2^14)
Q13 S2.13 -4≤x≤3.9998779
Q12 S3.12 -8≤x≤7.9997559
Q11 S4.11 -16≤x≤15.9995117
Q10 S5.10 -32≤x≤31.9990234
Q9 S6.9 -64≤x≤63.9980469
Q8 S7.8 -128≤x≤127.9960938
Q7 S8.7 -256≤x≤255.9921875
Q6 S9.6 -512≤x≤511.9804375
Q5 S10.5 -1024≤x≤1023.96875
Q4 S11.4 -2048≤x≤2047.9375
Q3 S12.3 -4096≤x≤4095.875
Q2 S13.2 -8192≤x≤8191.75
Q1 S14.1 -16384≤x≤16383.5
Q0 S15.0 -32768≤x≤32767
沒有留言:
張貼留言