定點數(shù)的加減其實可以歸為一類。
定點加減
定點加減運算主要用到補碼運算。
加法表達式為[X+Y]補=[X]補+[Y]補;就是說X+Y補碼的結(jié)果為X的補碼加上Y的補碼,即結(jié)果為補碼。
減法表達式為[x-y]補=[X]補+[-Y]補;就是說X-Y的補碼結(jié)果就是用加法表示的,是用X的補碼和-Y的補碼相加得到的。[-Y]補等于[Y]補各位取反,包括符號位,然后加1就得到了。
溢出
溢出就是給定一個固定的容器,容器里盛裝的液體溢出來了,我就不多解釋了。計算機中的溢出就是給了你一個固定的位數(shù)去盛放位數(shù),某個數(shù)在這個容器里裝不下了就是溢出。定點數(shù)的加減運算就會出現(xiàn)這種情況。
那么如何判斷加減溢出,粗糙的方法是正正相加為負溢出,負負相加為正溢出,正-負為負溢出,負-正為正溢出。
高端操作判斷溢出有個名字:變形補碼法,其實特別簡單,既可以看出溢出,也可以看出溢出的方向,是向正數(shù)方向溢出了還是負數(shù)方向溢出了,一目了然。
就是符號位用雙符號位表示就可以啦,就這么簡單。符號位為00、11為正負數(shù),若出現(xiàn)01、10則溢出了。01為上溢,10為下溢了。
定點數(shù)的乘法運算
主要有原碼一位乘、補碼一位乘。
原碼一位乘
符號位不參加運算,數(shù)值位均以絕對值出現(xiàn),X*Y中X為被乘數(shù),采用雙符號位,Y為乘數(shù),采用單符號位。部分積初始化為0。然后接下來的操作就是for循環(huán)了。
for(y的最低位;該位沒有超出y最高位;y的下一位)
{ 若y該位為1,部分積+X的絕對值,生成的新的部分積右移一位;
若y該位為0,部分積+0,生成的新的部分積右移一位;
}
結(jié)果表示:X符與Y符的異或產(chǎn)生的符號作為結(jié)果的符號。
補碼一位乘
符號位參與運算。
X*Y中,被乘數(shù)采用雙符號位,乘數(shù)采用單符號位,乘數(shù)的最低位后添加上一個附加位,附加位值為0,仍然存在部分積。
for(y的最右邊兩位(初始的話為附加位與原來的最低位);y的兩位不是小數(shù)點左右兩邊的數(shù);y向左挪動兩位)
{?
若y的兩位為00或11,則部分積+0,新的部分積右移兩位;
若y的兩位為01,則部分積+[X]補,新的部分積右移兩位;
若y的兩位為10,則部分積+[-X]補,新的部分積右移兩位;
}
其實到這了現(xiàn)在,應(yīng)該會發(fā)現(xiàn)原碼一位乘與補碼一位乘很相似,部分積都是要移動n次(即X、Y的最高有效位個數(shù))。
定點數(shù)的除法運算
原碼恢復(fù)余數(shù)法運算
符號位不參與運算,在X/Y中,X、Y的絕對值的補碼需要。雙符號位補碼運算。
步驟:for(i=1;i<=X、Y的最高有效位個數(shù);i++)
{
判斷X>Y?
如果X>Y,商1,生成結(jié)果左移1位;
如果X<Y,商0,生成結(jié)果+Y絕對值補碼,生成的結(jié)果左移1位;
}
結(jié)果為:商,余數(shù),上述中最后生成的結(jié)果就是余數(shù)的尾數(shù),余數(shù)由尾數(shù)與階碼表示,階碼一般為負數(shù),左移幾次就是幾,例如:M*2的-5次方,就是余數(shù)產(chǎn)生左移了5次。
由于符號位不參加運算,最后商的符號為X、Y的符號異或產(chǎn)生,余數(shù)的符號與被除數(shù)的符號相同。
原碼不恢復(fù)余數(shù)法運算
符號位不參加運算,參與運算的是絕對值的補碼加減。整個過程類似一個循環(huán)的判斷。假設(shè)余數(shù)最初為被除數(shù)。
判斷:余數(shù)>除數(shù),商1,結(jié)果左移1位,新生成的余數(shù)-除數(shù);
余數(shù)<除數(shù),商0,結(jié)果左移一位,新生的余數(shù)+除數(shù);
該判斷需要左移n次(即參與運算的數(shù)的有效位的個數(shù))。若左移第n次產(chǎn)生的余數(shù)為負,需加上除數(shù)使余數(shù)為正。余數(shù)的符號與被除數(shù)的符號一致。
補碼一位除
補碼一位除設(shè)計到校正問題,此處只針對精度不嚴格的除法。
運算:補碼雙符號位的加減。
規(guī)則:被除數(shù)(余數(shù))與除數(shù)同號,被除數(shù)(余數(shù))-除數(shù),若異號,被除數(shù)(余數(shù))+除數(shù);新生成的余數(shù)如果與除數(shù)同號,商1,結(jié)果左移一位;若新生成的余數(shù)如果與除數(shù)異號,商0,結(jié)果左移一位。如此往復(fù),直到左移發(fā)生了n次(即被除數(shù)、除數(shù)的有效位個數(shù))。
值得注意的是:最后一次上商,無論余數(shù)與除數(shù)是否同號,均商1。
到了現(xiàn)在,可以發(fā)現(xiàn),原碼的乘除沒有符號位直接參與運算,因而都是對絕對值進行操作的。