二进制的加减乘除实现

1. 加法

当二进制加法没有进位时,两个数的加法其实就是按位异或,例如3 + 4 = 7,011 + 100 = 111,这个结果就是按位异或得到的结果,但是我们的加法肯定是存在进位的,那我们进位怎么表示呢,我们想一下,我同样使用异或运算,当只考虑一位的时候(a表示其中一个数的第i位,b表示另外一个数的第i位),只有两个1才会有进位,这就和与运算是一样的,但是进位肯定是要往前移位的,所以进位可以表示为 a & b << 1

递归写法

public int sum(int a, int b) {
    // 如果b为0,则表示没有进位了,那么a就是结果
    if (b == 0) {
        return a;
    }
    return sum(a ^ b, (a & b) << 1);
}

非递归写法

public int sum(int a, int b) {
    while (b != 0) {
        // 保留a的值
        int t = a;
        a = a ^ b;
        b = (t & b) << 1;
    }
    return a;
}

2. 减法

减法可以转换为加法,就不赘述了,例如a - b = a + (-b)

3. 乘法

关于二进制的乘法,例如 110 * 1010101,a * b 我们可以以其中a为基准,判断a的最低位是否为1,如果最低位是1,则结果加上b,然后a右移一位,b左移一位,直到a等于0,最后的结果就是结果 + b,我们判断最低位是否为1是因为我们右移的时候会丢失这个1,其实就是一个数除2,另外一个数乘2,对于结果是没有影响的,例如 6 * 43 = 3 * 86 = 86 + (1 * 172) = 86 + 172,就是这样的一个过程
代码实现

public int mul(int a, int b) {
    int res = 0;
    while (a != 0) {
        if ((a & 1) == 1) {
            res += b;
        }
        a >>= 1;
        b <<= 1;
    }
    return res;
}

4. 除法(整数除法)

关于二级制的除法,其实和乘法是相反的,分为以下几个步骤,a / b,默认 b < a

  1. 将 b 的位数通过移位与 a 对齐,记为b1
  2. 如果 a >= b1,则 a = a - b1,res += 2 的(b的位数- b1的位数)次方,然后 b1 右移一位
  3. 如果 b1 大于等于 b,继续步骤 2
  4. 最后得到结果res,a 就是 a / b 的余数

整体过程描述:10 / 3

  • a = 10 b = 3 res = 0 b1 = 12
  • a = 10 b = 3 res = 0 b1 = 6
  • a = a - b1 = 4 b = 3 res += 2 ^ (3 - 2) = 2 b1 = 3
  • a = a - b1 = 1 b = 3 res += 2 ^ (2 - 2) = 2 + 1 = 3 b1 = 1

即最后的结果 res = 3,余数 a = 1
代码实现

// 默认a b和运算中的结果都在int范围内
// 默认都是正数,如果出现负数,则符号统一处理
public int div(int a, int b) {
    // 如果 a < b,直接返回0
    if (a < b) {
        return 0;
    }
    int count = 0; // 记录b移位的次数,即 b 和 b1 相差位数(二进制)
    int b1 = b;
    int res = 0; // 记录结果
    // 模拟移位
    while (b1 < a) {
        ++count;
        b1 <<= 1;
    }
    while (b1 >= b) {
        if (a >= b1) {
            a -= b1;
            res += (1 << count);
        }
        b1 >>= 1;
        --count;
    }
    return res;
}

PS: 这个除法并不适用于所有的 int 整数的除法,当出现一些特殊值时,可能导致溢出,例如Integer.MIN_VALUE等

  • 1
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在C语言中,二进制加减乘除运算可以通过位运算符来实现。以下是一些常用的位运算符: 1. 位与运算符(&):对应位上的两个数都是1,结果才为1。 2. 位或运算符(|):对应位上的两个数只要有一个是1,结果就为1。 3. 异或运算符(^):对应位上的两个数不相同,则结果为1,否则结果为0。 4. 取反运算符(~):对每个二进制位取反(0变成1,1变成0)。 以下是一些常见的二进制运算示例: 1. 二进制加法: ```c int a = 0b1010; // 十进制数10 int b = 0b1101; // 十进制数13 int sum = a ^ b; // 不进位相加结果,0b0111(十进制数7) int carry = (a & b) << 1; // 进位结果,0b1000(十进制数8) int result = sum | carry; // 最终结果,0b1111(十进制数15) ``` 2. 二进制减法: ```c int a = 0b1101; // 十进制数13 int b = 0b1010; // 十进制数10 int diff = a ^ b; // 不借位相减结果,0b0111(十进制数7) int borrow = ((~a) & b) << 1; // 借位结果,0b0100(十进制数4) int result = diff | borrow; // 最终结果,0b1011(十进制数11) ``` 3. 二进制乘法: ```c int a = 0b1010; // 十进制数10 int b = 0b1101; // 十进制数13 int result = 0; while (b != 0) { if (b & 1) { result += a; } a <<= 1; b >>= 1; } ``` 4. 二进制除法: ```c int a = 0b1101; // 十进制数13 int b = 0b101; // 十进制数5 int quotient = 0; int remainder = 0; for (int i = 31; i >= 0; i--) { remainder <<= 1; remainder |= (a >> i) & 1; if (remainder >= b) { remainder -= b; quotient |= 1 << i; } } ``` 以上是一些常见的二进制运算示例,需要注意的是,在进行二进制运算时,需要使用二进制数表示,并且在C语言中,整数默认是有符号的,因此需要注意符号位的处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值