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

Posted 炫云云

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指 Offer 65. 不用加减乘除做加法相关的知识,希望对你有一定的参考价值。

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

写一个函数,求两个整数之和,要求在函数体内不得使用 “+”、“-”、“*”、“/” 四则运算符号。

示例:

输入: a = 1, b = 1
输出: 2

提示:

  • a, b 均可能是负数或 0
  • 结果不会溢出 32 位整数

因为不允许采用四则运算,所以只能考虑位运算了。

其实就是用二进制来模拟加法操作。首先将两个数最低位相加,如果都是 1 ,那么就得到 0 ,并且进位 1 ,然后接着算下一位。

但是这样一位一位模拟不方便实现,更简单的实现方法是直接把两个数对应位相加,不管进位。然后进位单独计算,如果某一位两个数都是 1 ,那么进位就会对下一位产生影响。然后接着算不进位求和加上进位的值,再计算新的进位,依次重复下去,直到进位为 0 为止。

用一个实际的例子来演示一下,计算 3+7 的值,其中 ss 表示每一步不考虑进位的求和,c 表示每一步的进位,最后得到结果 1010,也就是十进制的 1010 :

但是这里还是用到了加法怎么办呢?因为是二进制,所以不考虑进位求和的话,可以直接采用异或运算。而计算进位的话,直接用位与左移一位就行了。

  • python 因为位数没有限制,所以负数补码会很长,所以要位与 0xffffffff 处理成 32位整型数。

  • 怎么把负数的补码还原成原码呢?

    首先思考:怎么将补码高位还原呢?我们可以将高于32的数位取反(0到1),但是直接取反会将低于32的数位也取反,所以我们先对低于32的数位做一次取反,再整体取反,就可以实现只对高于32的数位取反啦。
    对低于32的数位取反可以通过和0xffffffff异或来实现,这个异或操作也不会改变高于32的数位(0与0异或还是0)

class Solution:
    def add(self, a: int, b: int) -> int:
        a &= 0xffffffff
        b &= 0xffffffff
        while b != 0:
            carry = ((a & b) << 1) & 0xffffffff
            a ^= b
            b = carry
        return a if a < 0x80000000 else ~(a^0xffffffff)

参考

Krahets - 力扣(LeetCode) (leetcode-cn.com)

以上是关于剑指 Offer 65. 不用加减乘除做加法的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode-剑指Offer 65-不用加减乘除做加法

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

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

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

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

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