位的加减乘除

基于位的加、减、乘、除

/**
 * 基于位的加、减、乘、除
 *
 * @Author hweiyu
 * @Description
 * @Date 2021/12/8 10:12
 */
public class BitCalculation {

    public static void main(String[] args) {
        System.out.println(new BitCalculation().add(11, -10));

        System.out.println(new BitCalculation().sub(2, 8));

        System.out.println(new BitCalculation().mul(-2, -11));

        System.out.println(new BitCalculation().div(8, 2));

    }

    /**
     * 加
     *
     * 设a,b为两个二进制数,则 a + b = a ^ b + (a & b) << 1
     *
     * @param a
     * @param b
     * @return
     */
    public int add(int a, int b) {
        if (b == 0) {
            return a;
        }
        //a ^ b : 不进位相加
        //(a & b) << 1 : 进位
        return add(a ^ b, (a & b) << 1);
    }

    public int sub(int a, int b) {
        //a减b,其实就是a加负b。
        //先求负b,求一个数的负的操作是将其连符号位一起取反然后加1
        return add(a, negative(b));
    }

    //注意:没有处理 Integer.MIN_VALUE 的情况
    private int negative(int n) {
        //负n,就是将其连符号位一起取反然后加1
        return add(~n, 1);
    }

    private int abs(int n) {
        return n < 0 ? negative(n) : n;
    }

    /**
     * 乘
     *
     * 示例:
     *            1 0 0 1
     *         x  0 1 1 0
     *  -------------------
     *           0 0 0 0
     *         1 0 0 1
     *       1 0 0 1
     *  +  0 0 0 0
     *  -------------------
     *     0 1 1 0 1 1 0
     *
     * @param a
     * @param b
     * @return
     */
    public int mul(int a, int b) {
        //判断最终的结果是正是负
        //将原数往右移31位,即得到原数对应的符号位,判断符号位是否相同,不同则结果为负;相同则结果为正
        boolean isNegative = (a >> 31) != (b >> 31);
        //a取绝对值
        a = abs(a);
        //b取绝对值
        b = abs(b);
        int r = 0;
        while (b != 0) {
            if ((b & 1) == 1) {
                r = add(r, a);
            }
            a <<= 1;
            b >>= 1;
        }
        return isNegative ? negative(r) : r;
    }

    /**
     * 除
     *
     * 注意:没有处理 b = 0 和 Integer.MIN_VALUE 的情况
     *
     * @param a
     * @param b
     * @return
     */
    public int div(int a, int b) {
        //判断最终的结果是正是负
        //将原数往右移31位,即得到原数对应的符号位,判断符号位是否相同,不同则结果为负;相同则结果为正
        boolean isNegative = (a >> 31) != (b >> 31);
        //a取绝对值
        a = abs(a);
        //b取绝对值
        b = abs(b);
        int r = 0;
        int i = 31;
        while (i >= 0) {
            if ((a >> i) >= b) {
                r = add(r, 1 << i);
                a = sub(a, b << i);
            }
            i = sub(i, 1);
        }
        return isNegative ? negative(r) : r;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值