题目
代码分析
不使用算数运算符,首先想到的就是采用位运算,先完成加减的位运算方法,再实现乘除的位运算方法
代码展示
加的位运算实现
public static int add(int a,int b) { while(b!=0) { int temp=a^b; b=(a&b)<<1; a=temp; } return a; }
抑或和与运算的使用,举一个例子就是可以完成,比如说8+3
减的位运算实现
public static int opp(int a) { return ~a+1; } public static int minu(int a,int b) { b=opp(b); return add(a,b); }
这里比较重要的就是取相反数的操作
乘的位运算实现
public static int multi(int a,int b) { int sum=0; while(b!=0) { if((b&1)==1) { //sum+=add(a,0); sum=add(a,sum); } a<<=1; b>>>=1; } return sum; }
我们使用公式
res = ab02^0 + ab12^1 + ab22^2 + ab32^3 ........ +ab312^31
实现的思路大概就是判断b的每一位,因此核心思路如下
while(b!=0) { 一系列的操作 b向右移动 }
对于 一系列的操作 就是针对每一位的b进行操作,对于a乘以2的多少次方,我们可以直接移动a来实现
除的位运算实现
public static int division(int a,int b) { int tempa=a>0?a:opp(a); int tempb=b>0?b:opp(b); int res=0; for(int i=31;i>=0;i--) { if(multi(tempb,1)<=(tempa>>i)) { res|=(1<<i); tempa-=multi(tempb,1<<i); } } return (a>0&&b>0)||(a<0&&b<0)?res:opp(res); }
这里面是让被除数变小,不是除数变大
public static int divisionAll(int a,int b) { if(b==0) { throw new RuntimeException("b==0"); }else if(a==Integer.MIN_VALUE&&b==Integer.MIN_VALUE) { return 1; }else if(b==Integer.MIN_VALUE) { return 0; }else if(a==Integer.MIN_VALUE) { int c=division(add(a,1),b); int c2=division(minu(a,multi(b,c)),b); return add(c,c2); }else { return division(a,b); } }
对于除法一定要考虑边界,因为如果是32位数的最小值的话,是无法转化为正数的,所以我们可以让被除数加上一点,比如说1,将整个除法分为两个部分进行运算
学习情况
完成1次