No.29 Divide Two Integers
Divide two integers without using multiplication, division and mod operator.
If it is overflow, return MAX_INT.
Tags: Math Binary Search
计算dividend/divisor,不能用乘法、除法和模运算符
如果溢出,返回MAX_INT
误区:除法,得到结果仍为整数,其实就是dividend = n * divisor + b;别想得,太复杂
疑问:什么时候会溢出呢?
因为计算时,要将负数转为整数进行运算,所以-INT_MIN是会溢出的
另外,MAX_INT/-1 会溢出(注意正负范围的那点儿差异)
分析:
不能用乘、除和取模,那剩下的,还有加、减和位运算。
最简单的方法,是不断减去被除数。在这个基础上,可以做一点优化,每次把被除数翻倍,从而加速
即,对a/b来说,a-b-2b-4b-8b...,翻倍就是移位操作
1 #include "stdafx.h" 2 #include <string> 3 #include <iostream> 4 #include <unordered_map> 5 6 using namespace std; 7 8 9 class Solution 10 { 11 public: 12 int divide(int dividend, int divisor) 13 { 14 /* 15 计算dividend/divisor,不能用乘法、除法和模运算符 16 如果溢出,返回MAX_INT 17 误区:除法,得到结果仍为整数,其实就是dividend = n * divisor + b;别想得,太复杂 18 疑问:什么时候会溢出呢? 19 因为计算时,要将负数转为整数进行运算,所以-INT_MIN是会溢出的 20 另外,MAX_INT/-1 会溢出(注意正负范围的那点儿差异) 21 分析: 22 不能用乘、除和取模,那剩下的,还有加、减和位运算。 23 最简单的方法,是不断减去被除数。在这个基础上,可以做一点优化,每次把被除数翻倍,从而加速 24 参考:书 25 */ 26 // 当 dividend = INT_MIN 时,-dividend 会溢出,所以用 long long!!! 27 if(divisor == 0) 28 return INT_MAX;//返回这个吗?看题意吧 29 if(dividend == 0) 30 return 0; 31 32 long long a = dividend>0 ? dividend : -(long long)dividend; 33 long long b = divisor>0 ? divisor : -(long long)divisor; 34 35 // 当 dividend = INT_MIN 时,divisor = -1 时,结果会溢出,所以用 long long!!! 36 long long result = 0; 37 while( a >= b) 38 { 39 long long c = b; 40 for(int i=0; a >=c ; ++i,c <<= 1) 41 { 42 a -= c;//a每次减2^i*c 43 result += 1<<i;//result每次加2^i 44 } 45 } 46 // return ((dividend^divisor) >> 31) ? (-result) : result;//异或+移位,判断符号位!!!巧妙,两种方法都可以 47 if((dividend<0) ^ (divisor<0)) 48 result = -result; 49 // if((dividend^divisor) >> 31) 50 // result = -result; 51 if(result > INT_MAX || result < INT_MIN) 52 return INT_MAX; 53 return result; 54 } 55 }; 56 57 58 int main() 59 { 60 Solution sol; 61 62 cout <<" : "<< sol.divide(INT_MIN, -1)<<endl;//终极大挑战 63 return 0; 64 }
另外有一种方法应该也可以,但没有理解,觉得没有这种方法简单易懂些,参见:http://blog.csdn.net/linhuanmars/article/details/20024907