题目

代码分析

不使用算数运算符,首先想到的就是采用位运算,先完成加减的位运算方法,再实现乘除的位运算方法

代码展示

加的位运算实现

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次