剑指Offer 65. 不用加减乘除做加法(Easy)

在这里插入图片描述
【题目链接】

题解

  1. 不用加减乘除做加法(位运算,清晰图解)

思路

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码

class Solution:
    '''
    在计算机系统中,数值一律用补码来表示和存储。因为使用补码,可以将符号位和数值域统一处理,且加法和减法也可以统一处理!

    1.原码求补码:
    正整数的补码是其二进制表示,与原码相同
    负整数的补码,将其原码除符号位外的所有位取反(0变1,1变0,符号位为1不变)后加1

    2.补码求原码:
    正整数的补码就是原码
    负整数的补码的补码是原码
    '''

    ### 1206 位运算(36 ms,13.5 MB)
    def add(self, a: int, b: int) -> int:
        # 十六进制数 0xffffffff = 1111 1111 1111 1111 1111 1111 1111 1111 = 4294967295
        x = 0xffffffff
        # 循环迭代后:a表示当前无进位的总和,b表示总的进位
        # 获取负数的补码:将数字与十六进制数 0xffffffff 相与。可理解为舍去此数字 32 位以上的数字(将 32 位以上都变为 0),从无限长度变为一个 32 位整数
        a, b = a & x, b & x

        # 当进位b中还有进位1时(不为0),表示和还未加完,需要继续用位运算来表示相加
        while b:
            # 异或^:表示相加,与运算&结合左移<<:表示计算进位(注意:位运算优先级比逻辑运算高!)
            a, b = a ^ b, (a & b) << 1 & x

        # 十六进制数 0x7fffffff = 0111 1111 1111 1111 1111 1111 1111 1111 = 2147483647,表示正的最大有符号数(0表示正)
        # 若a > 0x7fffffff,则表示a为负数(在Python中是使用补码表示负数),因此需要将此补码还原为负数的原码
        # a ^ x 运算将 1 至 32 位按位取反; ~ 运算是将整个数字取反;因此, ~(a ^ x) 是将 32 位以上的位取反,1 至 32 位不变
        return a if a <= 0x7fffffff else ~ (a ^ x)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值