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; } };