0 题目
Divide two integers without using multiplication, division and mod operator.
If it is overflow, return MAX_INT.
意思是不适用除法,乘法,取模,计算两个数相除。
另外,如果越界,返回MAX_INT
1 分析
难点有两个:
- 越界检查
- 只能用加减和位运算
1.1 什么时候会越界
两个有符号数相除
- 当除数是0的时候,越界
- 当被除数是MIN_INT,除数是-1的时候,结果应该是INT_MAX+1.越界 (INT_MAX = -INT_MAX-1),最大值和最小值在绝对值上,最小值是要大1的。
1.2 使用加减计算除法
首相想到的是挨个相减,减一次,结果+1,但是,太慢。
因此需要成倍的减。
int divide(int a, int b) { if (b == 0) //判断除数为0, { return INT_MAX; } if (a == INT_MIN && b == -1) // 因为 INT_MIN 数值上比 INT_MAX 大 1 ,因此 INT_MIN/-1 会越界 { return INT_MAX; } int tmp_ret = 0; // 这一步判断需要在前面,因为(INT_MIN,INT_MIN)的情况。 if (a == 0) { return 0; } // 后面需要将 a,b 取绝对值运算,因此不能存在 a== INT_MIN // b 可以为 INT_MIN ,因为 abs 后 b 仍然等于 INT_MIN,这里没看懂!!! if (a == INT_MIN) { if (b < 0) { a -= b; ++tmp_ret; } else { a += b; --tmp_ret; } } bool sign = (a < 0 && b < 0) || (a > 0 && b > 0) ? true : false; a = abs(a); b = abs(b); int ret = 0; int tmp_b = b; while (a - tmp_b >= 0) { int ret_tmp = 1; while (a - tmp_b > tmp_b) { tmp_b += tmp_b;//每次递增 ret_tmp += ret_tmp; } a -= tmp_b; ret += ret_tmp; tmp_b = b; } return sign ? ret + tmp_ret : -ret + tmp_ret; }
有些步骤是根据调试出来的结果。因此有种投机取巧的感觉。