当前位置: 首页 > news >正文

使用位运算实现加法、减法、乘法和除法

使用位运算实现加法、减法、乘法和除法是一个经典的计算机科学问题。位运算通常用于低级程序设计和性能优化中,以下是如何用位运算实现这些基本数学运算。

加法

加法可以通过以下步骤实现:

def add(a, b):
    while b != 0:
        # 使用异或得到不考虑进位的加法结果
        sum_without_carry = a ^ b
        # 计算进位
        carry = (a & b) << 1
        # 更新 a 和 b
        a = sum_without_carry
        b = carry
    return a

减法

减法可以通过构造负数并使用加法来实现:

def subtract(a, b):
    # 通过补码法实现 a - b,即计算 a + (-b)
    while b != 0:
        # 使用异或获得不考虑借位的减法结果
        subtract_without_borrow = a ^ b
        # 计算借位,注意这里与加法中的进位不同,需要借位补偿
        borrow = (~a & b) << 1
        # 更新 a 和 b
        a = subtract_without_borrow
        b = borrow
    return a

# 或者使用add计算
def subtract(a, b):
    # 利用按位取反和加 1 获取 b 的补码,进而变为加法
    return add(a, add(~b, 1))

乘法

使用位运算实现乘法主要依赖于移位和加法。基本思想是默认为右移逐位提取因子:

def multiply(a, b):
    result = 0
    negative = (a < 0) ^ (b < 0)  # 判断结果符号
    a, b = abs(a), abs(b)

    while b > 0:
        if b & 1:  # 如果 b 的最低位是 1
            result = add(result, a)
        a <<= 1  # 左移 a,相当于 a * 2
        b >>= 1  # 右移 b,相当于 b // 2

    return -result if negative else result

除法

除法相对复杂,因为我们需要不断减去被除数直到不能再继续,同时记录减去了多少次:

def divide(dividend, divisor):
    if divisor == 0:
        raise ValueError("Cannot divide by zero")
        
    negative = (dividend < 0) ^ (divisor < 0)  # 判断结果符号
    dividend, divisor = abs(dividend), abs(divisor)
    result = 0

    # 试图将除数不断左移,通过以更大的尺度进行减法以提高效率
    while dividend >= divisor:
        temp, multiple = divisor, 1
        while dividend >= (temp << 1):
            temp <<= 1
            multiple <<= 1
        dividend -= temp
        result = add(result, multiple)

    return -result if negative else result

注意事项

这些操作假定整数可以表现为带符号或无符号的较大范围。如果在有限位宽的情况下,比如 32 位有符号整数需要特别注意溢出的处理。

代码较为基础与简化,未加入复杂错误处理,特别是在实际应用中,请根据需要添加错误处理。

实现效率上,使用 Python 原生运算符通常更为高效,但对于理解位级别操作上述实现具有学习价值。

相关文章:

  • 3.14学习总结 排序算法
  • 使用 VLOOKUP 和条件格式在 Excel 中查找并标红匹配的串号
  • 编程自学指南:java程序设计开发,网络编程基础,TCP编程,UDP编程,HTTP客户端开发
  • 扫描电子显微镜有何特点和用途?
  • Hello Mr. My Yesterday日文歌词附假名注音,祭奠逝去的青春
  • Spring 中 BeanFactoryPostProcessor 的作用和示例
  • Qt开发:QtWebEngine中操作选择文本
  • 【QT】文件系统相关 -- QFile
  • 上位机使用QtCharts绘图
  • linux 命令 tail
  • numpy.random 用法
  • 软文推广发布渠道有哪些适合作为首发平台?首发平台有哪些好处?
  • 200多种算法应用于二维和三维无线传感器网络(WSN)覆盖场景
  • Tomcat Session 反序列化漏洞(CVE-2025-24813)
  • ubuntu24.04执行nvidia-smi报错,实际生产报错,处理过程
  • Mybatis 框架学习
  • Android Composable 与 View 的联系和区别
  • 【xv6操作系统】页表与写时拷贝解析及相关实验设计
  • 简单说一说ADSP-BF537的开发
  • 前端无限滚动内容自动回收技术详解:原理、实现与优化
  • 国家发改委:不断完善稳就业稳经济的政策工具箱,确保必要时能够及时出台实施
  • 俄罗斯哈巴罗夫斯克市首次举办“俄中论坛”
  • 新华每日电讯:把纪律的螺丝拧得紧而又紧
  • 视觉周刊|走进变革中的博物馆
  • 从《缶翁的世界》看吴昌硕等湖州籍书画家对海派的影响
  • 重庆城市轨道交通拟听证调价:公布两套票价方案,正征求意见