本文共 1249 字,大约阅读时间需要 4 分钟。
参考自程序员代码面试指南
确定两个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<
转载地址:http://dryai.baihongyu.com/