Given two integers dividend and divisor, divide two integers without using multiplication, division and mod operator.
Return the quotient after dividing dividend by divisor.
The integer division should truncate toward zero.
Example 1:
Input: dividend = 10, divisor = 3
Output: 3
Example 2:
Input: dividend = 7, divisor = -3
Output: -2
Note:python
要求咱们实现两个整数的除法的操做,而且不能使用乘、除、模运算。两个整数都是32位整数,假设被除数是M,除数是m。ide
除法的溢出有两种状况:this
在除法操做中,同号为正,异号为负,这有点相似于异或操做:值相同异或为0,值不一样异或为1。因而咱们利用一个标志位来记录符号。再对被除数M和除数m取绝对值,这里注意,取绝对值时,因为32位整数范围为\([−2^{31}, 2^{31} − 1]\),在对除数m取绝对值时,必须将类型设置long或者long long型,不然当除数m为最小值时,取绝对值后会溢出。spa
题目要求不能利用乘、除、取模来实现除法。首先看除法的意义,假设36 / 9 = 4,将它换成36 - 9 - 9 - 9 - 9 = 0,这个时候发现能够用减法来逐渐逼近:36减去4次9等于0,而36除以9也是4(实际上减去减去4次9就是9 *4了)。另外一种状况是:若是不能整除怎么办?假设36 / 8 ,它的商是4。换成36 - 8 - 8 - 8 - 8 =4 < 8,这个时候发现不够减了,就不减了,商正好是4。因而咱们能够用一个循环来实现除法操做:看被除数M减去了几回除数m,将减去屡次m后的值与m比较(小于等于m时),获得商。
可是,这种每次只减一个除数m的循环太慢了,程序很容易超时。咱们但愿每次能够多减几个m,好比2的倍数次。为何是2的倍数次?由于两次能够用位运算实现。
m << 0 至关于m * 1
m << 1 至关于m * 2
m << 2 至关于m * 4
因而咱们须要利用一个变量i来记录位运算的移动次数,以及一个临时变量来记录除数m的左移操做以后的结果(m << i)。
此时的循环变为M 与 m << i比较。.net
|| | | |
| :---: | :---: | :---: |
| & | 逻辑与 | 0 & 1 =0 |
| | | 逻辑或 | 0 | 1 = 1 |
| ^ | 异或 | 0 ^ 1 = 1 |
| ~ | 逐位求反 | ~1 = 0 |
| << | 左移 | 8 << 1 = 16 |
| >> | 右移 | 8 >> 1 = 4 |
| <<= | 左移后赋值 | a <<=1 即 a= a<<1 |
| >>= | 右移后赋值 | a >>=1 即 a= a>>1 |code
class Solution { public: int divide(int dividend, int divisor) { //首先考虑特殊状况:溢出 if(divisor == 0 || (dividend == INT_MIN && divisor == -1)) return INT_MAX; //异或操做处理正负号 bool isNeg = ((dividend < 0) ^ (divisor < 0)); long m = abs((long)dividend); //被除数 long n = abs((long)divisor); //除数,这里必须是long或者long,不然取绝对值后会溢出。 long result = 0; //商 long count = 0; //记录次数 while(m >= n){ long tempVal = n; //记录左移操做的中间结果 count = 0; //每次乘以2,直到不能减为止 while(m >= (tempVal << 1)){ count ++; tempVal <<= 1; } m -= tempVal; result += 1 << count; } return isNeg ? -result : result; } };
[1] https://blog.csdn.net/a1351937368/article/details/77746574/blog