leetcode 29 整数相除 c语言
int divide(int dividend, int divisor) {
//唯一可能的越界情况
if(dividend == INT_MIN && divisor == -1)
return INT_MAX;
//单独对divisor == INT_MIN 进行的处理
if(divisor == INT_MIN)
return dividend==INT_MIN?1:0;
int flag = 0;
int ans = 0;
//判断两个int是否同符号
if((dividend^divisor)&0x80000000)
flag = 1;
int plus = 0;
//负转正可能越界
if(dividend<0)
{
if(dividend==INT_MIN)
{
//单独处理越界情况
plus = 1;
dividend = INT_MAX;
}
else
{
dividend = -dividend;
}
}
if(divisor<0) divisor = -divisor;
for(int i=31;i>=0;--i)
{
if(divisor<=(INT_MAX>>i))
{
if(dividend >= (divisor<<i))
{
dividend = dividend - (divisor<<i);
if(plus)
{
dividend +=plus;
plus = 0;
}
ans += (1<<i);
}
}
}
//下面注释错误
//由于plus存在 导致原本可以整除,但是实际上缺失plus导致的不能整除轮后裔
//例如:8/2
//8/8 ans =8
//7/4 ans = 4
//(3+1)/2 ans = 4+2
//2/1 ans = 4+2+1
//最后仍剩余1
//只有在dividend = INT_MIN时候出现
while(dividend >= divisor)
{
ans ++;
dividend -=divisor;
}
return flag?-ans:ans;
}
评论 实际上没有考虑INT_MIN/1的情况导致ans越界
恰巧答案一致,所以通过。
最后的while(dividend >= divisor)也不是因为plus导致的
因为程序是以 a=b*2^n+b*2^(n-1)+...+b
防止b溢出,所以判断了 b<=INT_MAX/2^n
实际上b*2^n==INT_MAX+1的时候没有溢出
导致判断溢出错误。
可以改为下面的判断方法
-------------------------------------------------------------------------------
网上改进:
可以通过long long divid = dividend;
从而省掉plus
但是注意 divid = (long long )INT_MAX +1 ;//必须这么写 不然编译器认为右面是int会越界,给divid就成了INT_MIN的值
-------------------------------------------------------------------------------
网上改进2: