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