一、加法
例子: 8+11=19 ,其二進制的加法形式爲
由a^b可以得出相加後沒有進位的和
由a&b可以得出相加後產生進位的地方
由(a&b)<<1可以產生進位後的值
那麼a^b(沒有進位的值)+(a&b)<<1(進位的值)==a+b ,不斷的重複啥時候不進位了啥時候終止
分步進行:
那麼根據 a^b ,其異或的二進制形式爲
那麼a&b ,其且的二進制形式爲
那麼(a&b)<<1 其二進制形式爲
代碼實現:
public static int add(int a,int b){
// 不進位了--終止條件
if(b ==0){
return a;
}
// 獲得求和位(沒有進位的時候)
int s = a^b;
// 獲得進位,然後需要向做移動一位表示進位
int c = ((a&b)<<1);
return add(s,c);
}
實現結果:
public static void main(String args[])
{
int a=8;
int b=11;
System.out.println(add(a, b));
}
二、減法
首先a-b相當於a+(-b) ,那麼就而-b=~(b-1) (因爲負數在計算機中存儲的爲補碼的形式,而補碼就是按位取反+1,反過來不就是-1然後再取一次反) ,那麼a-b=a+(-b)=a+(~(b-1))
實現代碼:
public static int minus(int a,int b)
{ int B=~(b-1);
return add(a, B);
}
實現結果:
public static void main(String args[])
{
int a=8;
int b=11;
//. System.out.println(add(a, b));
System.out.println(minus(a, b));
}
三、乘法
例如:1011*1010 ,因爲二進制運算的特殊性,可以將該乘法運算表達式拆分成兩個運算,1011*0010+1011*1000。而對於二進制運算,左移一位,等價於乘以0010,左移兩位,等價於乘以0100,左移三位,等價於乘以1000,所以兩者的乘積爲10110+1011000==1101110。 而最後一個1可以通過n&~(n-1)來獲取,最後通過n&(n-1)來清除掉。---摘自別人
public int multi(int a,int b)
{
int i=0;
int res=0;
while(b!=0)
{ //乘數爲零爲終止條件
if((b&1)==1)
//如果最後一位爲1
{
res=res+(a<<i);
b=b>>1;
//乘數左移一位
++i;//記錄移動的位數
}
else
{ //如果爲0,那麼就不加
b=b>>1;
++i;//但是仍然移位
}
}
return res;
}
過程:
四、除法
例子:7/2 說的就是7包含幾個2,過程爲
7-2=5(i=1 ) 5-2=3(i=2) 3-2=1(i=3) 1-2=-1(終止 a<b)
那麼除法就可以轉化爲減法(減法再轉化爲加法,好像計算機組成原理中也是這麼做的)
//除法
public int sub(int a,int b)
{
int res=-1;
if(a<b)
return 0;
else
res=sub(minus(a, b), b)+1;
//輾轉相減
}
(再寫一個關於應用位運算的算法)