只用位运算不用算术运算实现整数的加减乘除运算
程序员文章站
2022-03-11 16:15:37
...
参考自程序员代码面试指南
题目:
确定两个32位整数a和b,可正可负、可0。不能使用算术运算符,分别实现a和b的加减乘除运算。
要求:如果给定的a和b执行加减乘除的某些结果本来就会导致数据的溢出,那么你实现的函数补习对那些结果负责。
用位运算实现加法运算,如果在不考虑进位的情况下,a^b就是正确结果,因为0加0位0(0&0),0加1位1(0&1),1加0为1(1&0),1加1为0(1&1);
在只算进位的情况下,也就是只考虑a加b的过程中进位产生的值时什么,结果就是(a&b)<<1,因为在第i位上只有1与1相加才会产生i-1位的进位。
把完全不考虑进位的相加值与只考虑进位的产生值再相加,就是最终的结果。也就是说,一直重复这样的过程,知道进位产生的值完全消失,说明所有的过程都加完了。
public int add(int a,int b){
int sum=a;
while(b!=0){
sum=a^b;
b=(a&b)<<1;
a=sum;
}
return sum;
}
用位运算实现减法运算,实现a-b只要实现a+(-b)即可,根据二进制数在机器中表达的规则,得到一个数的相反数,就是这个二进制数表达取反加1(补码)的结果。具体如下:
public int negNum(int n){
return add(~n,1);
}
public int minus(int a,int b){
return add(a,negNum(b));
}
按位运算实现乘法运算。a*b的结果可以写成a*2^0*b0+2*2^1*b1+...+a*2^i*bi+...+a*2^31*b31,其中bi是表示0或1代表整数b的二进制数表达中第i位的值:
public int multi(int a,int b){
int res=0;
while(b!=0){
if((b&1)!=0){
res=add(res,a);
}
a<<=1;
b>>=1;
}
return res;
}
用位运算实现除法运算,其实就是乘法的逆运算。
public int div(int a,int b){
int x=isNeg(a)?negNum(a):a;
int y=isNeg(b)?negNum(b):b;
int res=0;
for(int i=31;i>-1;i=minus(i,1)){
if((x>>i)>y){
res|=(1<<i);
x=minus(x,y<<i);
}
}
return isNeg(a)^isNeg(b)?negNum(res):res;
}
上一篇: 叔叔干她去
下一篇: 字符串中数字子串求和