位运算实现加法

位运算加法
#include <stdio.h>
#include <assert.h>

#define __DEBUG__       1

int MyAdd(int a, int b)
{
    /* 定理1:
     * if (0 == (a & b)) {
     *     a + b == a ^ b;
     * }
     * 换句话说就是,如果两数相加时没有进位,则加法运算可由异或运算代替。
     * 两数相与生存下来的位就是相加会向左产生进位的位,所以
     * (a & b)就可以判断两数相加会不会产生进位,而且(a & b) << 1
     * 就是所有--进位位--的进位值之和。
     * */
    /* 定理2:a + b = a ^ b + ((a & b) << 1)
     * 就是把加法拆成--每位相加的和--与--进位值--两部分相加
     * 等式右边也是加法,又可以拆,这就形成了一个递归的过程
     * 要使递归终止,需使用定理1,也就是不再有进位,定理2等式右边
     * 的加号就可以换成异或符号。
     * */

    /* 这里的a, b可视为某两个数A和B的--每位相加的和--和--进位值 */
    int cf = a & b;
    int sum = a ^ b;

    while (cf) {
        a = sum;
        b = cf << 1;
        cf = a & b;
        sum = a ^ b;
    }

    #if __DEBUG__
    assert(sum == a + b);
    #endif

    return sum;
}

### 使用位运算实现加法的算法示例 #### 1. 位运算实现加法的基本原理 在二进制加法中,可以将加法分为两个部分:非进位部分和进位部分。非进位部分可以通过按位异或运算 `^` 实现,而进位部分可以通过按位与运算 `&` 和左移操作 `<<` 实现。最终结果是将非进位部分和进位部分不断迭代相加,直到没有新的进位产生[^3]。 #### 2. 算法步骤 - 非进位部分通过按位异或运算计算:`sum = num1 ^ num2`。 - 进位部分通过按位与运算和左移一位计算:`carry = (num1 & num2) << 1`。 - 当进位部分不为0时,重复上述过程,直到进位部分为0。 #### 3. 示例代码 以下是一个使用位运算实现加法的完整示例: ```python def add(num1, num2): while num2 != 0: # 计算非进位部分 sum_without_carry = num1 ^ num2 # 计算进位部分 carry = (num1 & num2) << 1 # 更新num1和num2 num1 = sum_without_carry num2 = carry return num1 # 测试用例 result = add(5, 3) print(result) # 输出8 ``` #### 4. 解释 - 在第一次循环中,`sum_without_carry = 5 ^ 3 = 6`,`carry = (5 & 3) << 1 = 2`。 - 第二次循环中,`sum_without_carry = 6 ^ 2 = 4`,`carry = (6 & 2) << 1 = 0`。 - 当进位部分为0时,退出循环,返回结果 `4 + 2 = 6` 再加上之前的进位部分 `2`,最终结果为 `8`[^3]。 #### 5. 负数处理 对于负数的处理,需要特别注意二进制补码表示方式。在大多数编程语言中,整数以补码形式存储,因此直接使用上述方法即可正确处理负数加法[^2]。 #### 6. 复杂度分析 该算法的时间复杂度为 O(log N),其中 N 是输入数字的最大值。这是因为每次迭代都会将进位部分左移一位,导致有效位数逐渐减少。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值