leetcode 29两数相除

 

我理解本题是考察基于加减实现除法,代码如下:

class Solution {
public:
    //只用加减号实现除法,
    //不用加减号实现除法;
    int divide(int dividend, int divisor) {
    //
        if(dividend==INT_MIN&&divisor==-1){
            return INT_MAX;
        }
        long dvd=labs(dividend);long dvs=labs(divisor);long ans=0;
        int sign=dividend^divisor;
        for(int i=31;i>=0;i--){
            if((dvd>>i)>=dvs){
                dvd-=dvs<<i;
                ans+=1<<i;
            }
        }
        if(sign<0)
            ans=-ans;
        return ans;
    }

};

 如果单纯基于位运算呢?加减也依靠位运算如何避免溢出?

以下为不使用“+ - * / ”四个符号完成计算:

class Solution {
public:
    //只用加减号实现除法,
    //不用+ - * / 实现除法;
    const int minus_one=substract(0,1);
    int divide(int dividend, int divisor) {
        if (dividend == INT_MIN && divisor == minus_one) {
            return INT_MAX;
        }
        long dvd = long(dividend<0?add(~dividend,1):dividend), dvs = long(divisor<0?add(~divisor,1):divisor), ans = 0;
        if(dividend==INT_MIN) dvd=2147483648;
        if(divisor==INT_MIN) dvs=2147483648;
        /**test for some cases
        cout<<dvd<<","<<dvs<<endl;
        cout<<labs(dvd)<<","<<labs(dvs)<<endl;
        cout<<add(~divisor,1); **/
        
        int sign = dividend > 0 ^ divisor > 0 ? minus_one : 1;
        while (dvd >= dvs) {
            long temp = dvs, m = 1;
            while (temp << 1 <= dvd) {
                temp <<= 1;
                m <<= 1;
            }
            dvd =substract(dvd,temp);
            ans =add(ans,m);
        }
        return sign>0?ans:substract(0,ans);
    }
    int add(int a,int b){
        long long carry=b;
        while(b!=0){
            carry=a&b;
            a=a^b;
            b=(carry&0xffffffff)<<1;//避免负数左移溢出
        }
        return a;
    }
    int substract(int a,int b){
        int c=add(~b,1);
        int res=add(a,c);
        return res;
    }
};

 

posted @ 2019-05-30 14:06  Joel_Wang  阅读(549)  评论(0编辑  收藏  举报