位操作实现加减乘除
一、常見功能的位操作實現:
(1)常用的等式:-n = ~(n-1) = ~n+1;
(2)獲取整數n的二進制中最右邊一個1:n&(-n)或者n&~(n-1),如:n=010100,則-n=101100,n&(-n)=000100;
(3)去掉整數n的二進制中最右邊一個1:n&(n-1),如:n=010100,n-1=010011,n&(n-1)=010000。
?
二、位操作實現加法
1、原理:主要思想是將加法的計算結果分解為兩部分:第一是不考慮進位的運算結果,第二是進位,然后再將這兩者相加,即得到結果。詳細表述如下:
(1)不考慮進位的計算結果,以一位二進制數來表示:
1+1=0
1+0=1
0+1=1
0+0=0
這個過程可以用異或位運算符來表示,即:
1^1=0
1^0=1
0^1=1
0^0=0
則a^b表示不考慮進位的計算結果。
(2)進位,同樣以一位二進制數表示:
0+0→不進位
0+1→不進位
1+0→不進位
1+1→進位,即相當于是10,將10加到不考慮進位的計算結果上,即可得到整個的計算結果,而可以用位運算的與操作和向左的移位操作即可模擬上述的是否進位:
0&0=0 ??????(0&0)<<1=0
0&1=0 ??????(0&1)<<1=0
1&0=0 ??????(1&0)<<1=0
1&1=1 ??????(1&1)<<1=10
如此,即將運算結果計算出來了。接下來,需要按照遞歸的方式將上述思想實現,主要原因是將運算結果分為不考慮進位的運算結果A和進位值B,則計算結果為A+B,但該運算可能還是會產生進位,故將A和B再次采用這種計算方法進行計算,直到進位部分為0,即表示上次加法計算沒有進位,則上次加法計算的不考慮進位的運算結果,即為整個加法計算的結果。例子如下:
2、代碼實現
(1)不用遞歸:
int getSum(int a, int b) {int add, carry;do{add = a^b;carry = (a&b) << 1;a = add;b = carry;} while (carry != 0);return add; }(2)遞歸實現:
int getSum(int a, int b) {if (!b)return a;elsereturn getSum(a^b, (a&b) << 1); }
三、位操作實現減法
減法化為加法,即a-b=a+(-b)。代碼實現:
int subtraction(int a, int b) {return getSum(a,getSum(~b,1)); }四、位操作實現乘法
unsigned int multiply(unsigned int a, unsigned int b) {int i;int result;for (i = 0; i < 8 * sizeof(unsigned int); i++)//b是被乘數,a是乘數,判斷a的二進制中為1的位所在的位置,讓b左移相應的位置,然后相加if (a&(1 << i))result += b << i;return result; }五、位操作實現除法 int Pos_Div(int x, int y)// x/y,代碼得到結果的整數部分 {int ans = 0;for (int i = 8*sizeof(int)-1; i >= 0; i--){//比較x是否大于y的(1<<i)次方,避免將x與(y<<i)比較,因為不確定y的(1<<i)次方是否溢出 if ((x >> i) >= y){ans += (1 << i);x -= (y << i);}}return ans; }
代碼解釋,考慮 8 / 3 :
? ? ?8 ? ?0000 ?1000
/ ? ?3 ? ?0000 ?0011
--------------------------
? ? ? ? ? ? ? ? ? ? ? ? ?100
if ((x >> i) >= y)//這句代碼可以反過來講,(x >> i) >= y 等價于(x >> i)<<i >= y<<i,即 x>=y<<i,也就是說假如y<<i不溢出,y左移位數如果大于i,y就大于x了;
//y的左移<=>x的右移,y左移=>y不動,作為商的1左移相應位數,和y相乘的話,y也就左移相應位數了,此時商的最高不為0的位為1 << i。接下來剩余的數x -= (y << i)同樣的操作。
總結
- 上一篇: 字符设备驱动基础篇3——字符设备驱动工作
- 下一篇: macbook查看java版本,Mac下