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