Divide Two Integers
Divide two integers without using multiplication, division and mod operator.
思路:
核心思想是:令试除数等于除数,如果试除数小于被除数,那么试除数乘二,商乘二,继续比较;否则试除数除二,商除二,被除数减去试除数,重新开始。这其实就是类似二分搜索法。
题目有一些边边角角的特殊情况,比如int的最大值比最小值的绝对值小1之类的。所以比较繁琐。
题解:
class Solution {
public:
int divide (int dividend, int divisor)
{
// assert (divisor != 0);
if (divisor == 1)
return dividend;
else if (divisor == -1)
return -dividend;
// verify the sign of the result
const int flag_sgn = (1 << (sizeof (int) * 8 - 1));
bool sgn = true; // positive
if ( (dividend & flag_sgn) ^ (divisor & flag_sgn))
sgn = false; // negative
// check if the negative number is numeric_limits<int>::min()
// this requires special care, as abs(INT_MIN) = INT_MAX + 1
if (dividend == numeric_limits<int>::min())
{
switch (divisor)
{
case 1:
return dividend;
case -1:
// problematic
return -dividend;
case 2:
return - (numeric_limits<int>::max() >> 1) - 1;
case -2:
return (numeric_limits<int>::max() >> 1) + 1;
case numeric_limits<int>::min():
return 1;
default:
dividend = numeric_limits<int>::max();
}
}
if (dividend < 0) dividend = - dividend;
if (divisor < 0) divisor = - divisor;
// now do the real job
while (! ( (divisor) & 1))
divisor >>= 1, dividend >>= 1;
int result = 0;
while (dividend > 0)
{
int trial = divisor;
int accumu = 1;
bool overflow = false;
while (trial <= dividend)
{
if (trial > (numeric_limits<int>::max() >> 1))
{
overflow = true;
break;
}
trial <<= 1, accumu <<= 1;
}
if (!overflow) trial >>= 1, accumu >>= 1;
dividend -= trial;
result += accumu;
}
if (!sgn)
result = - result;
return result;
}
};