原題鏈接29. 兩數相除 - 力扣(LeetCode)
主要不能用乘除取余,于是用位運算代替:
Java題解
class Solution {public int divide(int dividend, int divisor) {//全都轉為負數計算, 避免溢出, flag記錄結果的符號int flag = 1;if(dividend < 0) {flag = -flag;}else {dividend = -dividend;}if(divisor < 0) {flag = -flag;}else {divisor = -divisor;}int div = divisor;// -(用多少個負數的divisor)int ans = 0;while(div >= dividend) {// 記錄這次用了多少個divisor的負數 (避免溢出)int numDiv = -1;// 如果div乘二后不溢出并且小于被除數剩下的值則乘二,本次用的divisor數量也乘二while((div << 1) < div && (div << 1) >= dividend) {numDiv = numDiv << 1;div = div << 1;}// 被除數減去 負數的divisor * (-numDiv)dividend -= div;// 增加用的divisor數量ans += numDiv;// 重置除數div = divisor;}// 兩個三十二位整數合法相除,只有可能正溢出,不可能負溢出,判斷特殊條件if(ans == Integer.MIN_VALUE && flag == 1) {return Integer.MAX_VALUE;}else if(flag == 1) { // ans為不帶符號的商的負數return -ans;}else {return ans;}}
}
????????記錄下比較有意思的點,我原來返回結果寫的是 -flag * ans,因為擔心在ans為Integer.MIN_VALUE,flag為-1時寫(flag * (-ans))會溢出,但是試了下 -1 *? (-(-2147483648)) 的結果居然是?-2147483648,并沒有想象中的奇怪值。實際上它的補碼10000000 00000000 00000000 00000000, 取負數以后仍然是10000000 00000000 00000000 00000000, 先按位取反得到:01111111 11111111 11111111 11111111, 加一10000000 00000000 00000000 00000000,又變回原來的了,java是靜默溢出,-1 *? (-(-2147483648))會溢出兩次,但是結果仍不變