一、加法
例子: 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;
//辗转相减
}
(再写一个关于应用位运算的算法)