29. 兩數相除
#include <iostream>
using namespace std;
class Solution {
public:
int add(int a, int b) {
int res = a;
while (b != 0) {
// 無進位相加的結果
res = a ^ b;
// 相加時每一位的進位資訊
b = (a & b) << 1;
// 無進位相加的結果
a = res;
// 如果進位資訊 b 不全是 0 的話,仍需將進位資訊 b 與無進位相加的結果 a 繼續相加
}
return res;
}
// 補碼:原碼按位取反再加一
int neg(int n) {
return add(~n, 1);
}
int minus(int a, int b) {
return add(a, neg(b));
}
int multiply(int a, int b) {
int res = 0;
while (b != 0) {
if ((b & 1) != 0)
res = add(res, a);
// 算數左移
a <<= 1;
// 邏輯右移
b = (unsigned int) b >> 1;
}
return res;
}
// 必須保證 a 和 b 都不是整數最小值,返回 a 除以 b 的結果
int div(int a, int b) {
int x = a < 0 ? neg(a) : a;
int y = b < 0 ? neg(b) : b;
int res = 0;
for (int i = 30; i >= 0; i = minus(i, 1)) {
if ((x >> i) >= y) {
res |= (1 << i);
x = minus(x, y << i);
}
}
return a < 0 ^ b < 0 ? neg(res) : res;
}
const int MIN = INT_MIN;
const int MAX = INT_MAX;
int divide(int a, int b) {
// a 和 b 都是整數最小
if (a == MIN && b == MIN) return 1;
// a 和 b 都不是整數最小,正常除
if (a != MIN && b != MIN) return div(a, b);
// a 不是整數最小,b 是整數最小
if (b == MIN) return 0;
// a 是整數最小,b 是 -1,返回整數最大,因為題目裡明確這麼說了
if (b == neg(1)) return MAX;
// a 是整數最小,b 不是整數最小,b 也不是 -1
a = add(a, b > 0 ? b : neg(b));
int res = div(a, b);
int offset = b > 0 ? neg(1) : 1;
return add(res, offset);
}
};