位运算实现加减乘除

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)) {
            // 如果 x 中包含 y * 2^i
            if ((x >> i) >= y) {
                res |= (1 << i);
                // x 减去 y * 2^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 变大一点,最终结果再减去 1 或者 加上 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);
    }
};
posted @ 2024-09-21 17:54  n1ce2cv  阅读(5)  评论(0编辑  收藏  举报