1. 程式人生 > >計算機中如何實現除數是2的冪次的除法

計算機中如何實現除數是2的冪次的除法

前言:

本來是在看彙編裡面的資料條件傳送指令,做習題的時候看著這麼一道有關於2的冪次方除法的題目。結果傻眼了,又尼瑪不會了。。。。。。。。。第二章看的時候就稀裡糊塗的,看了幾遍也沒看太懂,這回又涉及到了 ,發現再回來看還是容易一點。所以寫此博文,方便日後複習。

我今天遇到的問題如下:


問題:

除法,在我們平時的算數運算中,結果總是向0的方向舍入的,但是在計算機中,舍入的方式有所不同。在大多數的機器中,除法要比乘法還有加法這些運算都要慢很多倍,計算機中對於2的冪次這種數很是敏感,因為計算機當中用到的指令和進位制本來就是二進位制的形式,計算機用這種方式運算是最快的。所以,在做除法時如果除數是2的冪次,那麼我們就可以進行一些優化,讓運算做到更加快速。

解決辦法:

因為左移運算相當於是乘以2,右移運算相當於除以2.所以說當我們的除法的除數是2的冪次方的時候,利用單純的移位運算要比利用普通方法快的多。

對於無符號數來說, 如果除數是2的k次冪,那麼我們就會把被除數啊相應的做算數右移操作,右移k位。這樣的結果和平時我們做除法的結果是一樣的。

對於無符號數來說,假設x是一個有w位的二進位制數,x'是從第w位到k位的序列,x''是0-k位的序列。那麼x' =floor(x/2^k),這個表示式是可以證明的,過程還是很easy的我就不多說了。

對於一個無符號數還有一個有符號數的非負數來說的話,除以2的k次冪和把被除數右移k位的結果是一樣的


但是對於有符號數的負數來說,就會有一些差錯。


在 十進位制那一欄裡面是計算機的計算結果舍入之後的結果,最右邊一欄是計算機算的結果,我們可以看出來,在整除也就是不需要舍入的時候,結果和右移k位的操作是一樣的,但是如果一旦沒有整除需要進行舍入的時候,我們就會發現出了問題了,移位導致它不是向0舍入而是向下舍入,-771.25按理說應該舍入為-771,但是他卻舍入到了-772.

在平時進行手算除法的時候,我們的結果統一都是向0舍入的,但是在計算機中確實向下舍入,因為非負數向下舍入就是向0舍入所以不會有影響,但是負數的話就不會了。因為移位之後,負數在左邊補充的是最高的符號位,而不是0.負數在做除法的 時候應該是向上舍入才符合手算中向0舍入的規則。

對於負數除法向0舍入的解決辦法:

為了保證正確的舍入方式,我們決定利用一個偏置值來解決這個問題。

對於任何整數x和y>0,有ceil(x/y) = floor((x+y-1)/y)

假設x=ky + r (r>=0 && r < y)

我們就可以清楚(x+y-1)/y = (ky+ r - 1)/y = k + (r + y - 1)/y

如果此時x能整除y,即r = 0,那麼ceil(x/y) = floor((x+y-1)/y) = k

否則的話等於k + 1那麼也就是說,在計算被除數是負數,除數是2的冪次的除法的時候,可以給x加上除數-1(y-1)這個偏移量,即可保證除法的結果是正確的,因為在除數是2的冪次的時候,才能夠用右移操作來進行替代,則當被除數是負數的時候,要給他加上2^k - 1這個偏移量,才能夠得到正確的結果。

所以在計算機內如果除數是2的冪次的時候,是會用向下面的這個表示式的形式去計算除法的的

(x < 0 ? x + 2^k -1:x) >> k