# -*- coding:utf-8 -*-
# 写一个函数，求两个整数之和，要求在函数体内不得使用 +、-、 * 、 / 四则运算符号。
# https: // blog.csdn.net / zhongjiekangping / article / details / 6855864
# 用位运算实现加法也就是计算机用二进制进行运算，32
# 位的CPU只能表示32位内的数，这里先用1位数的加法来进行，在不考虑进位的基础上，如下
#
# 1 + 1 = 0
# 1 + 0 = 1
# 0 + 1 = 1
# 0 + 0 = 0
#
# 很明显这几个表达式可以用位运算的“ ^ ”来代替，如下
#
# 1 ^ 1 = 0
# 1 ^ 0 = 1
# 0 ^ 1 = 1
# 0 ^ 0 = 0
# 这样我们就完成了简单的一位数加法，那么要进行二位的加法，这个方法可行不可行呢？肯定是不行的，矛盾就在于，如何去
# 获取进位？要获取进位我们可以如下思考：
#
# 0 + 0 = 0
# 1 + 0 = 0
# 0 + 1 = 0
# 1 + 1 = 1
# // 换个角度看就是这样
# 0 & 0 = 不进位
# 1 & 0 = 不进位
# 0 & 1 = 不进位
# 1 & 1 = 进位
# 正好，在位运算中，我们用“ << ”表示向左移动一位，也就是“进位”。那么我们就可以得到如下的表达式
#
# // 进位可以用如下表示：
# (x & y) << 1
# 到这里，我们基本上拥有了这样两个表达式
#
# x ^ y // 执行加法
# (x & y) << 1 // 进位操作
# 我们来做个2位数的加法，在不考虑进位的情况下
#
# 11 + 01 = 100 // 本来的算法
#
# // 用推算的表达式计算
# (11 & 01) << 1 = 10
# 11 ^ 01 = 10
#
# // 到这里
# 我们用普通的加法去运算这两个数的时候就可以得到
# 10 + 10 = 100
# // 但是我们不需要加法，所以要想别的方法，如果让两个数再按刚才的算法计算一次呢
# (10 & 10) << 1 = 100
# 10 ^ 10 = 00
#
# 到这里基本上就得出结论了，其实后面的那个 “00” 已经不用再去计算了，因为第一个表达式就已经算出了结果。
# 继续推理可以得出三位数的加法只需重复的计算三次得到第一个表达式的值就是计算出来的结果。
# 其余基础知识：关于原补反，计算机中整数都是以补码形式存储的。正数的原反补是一样的，
# 而负数的原码是符号位置1；负数的反码是在原码的基础上，符号位不变，其余位置取反；负数的补码是在反码的基础上再加1。
# [+1] = [00000001]原 = [00000001]反 = [00000001]补
# [-1] = [10000001]原 = [11111110]反 = [11111111]补
class Solution:
    def Add(self, carry, sum):
        if carry == 0:
            # // a = ~b +1,b = ~(a-1)
            return sum if sum <= 0x7FFFFFFF else -(~(sum - 1) & 0x7FFFFFFF)
        return self.Add((carry & sum) << 1, (carry ^ sum) & 0x7FFFFFFF)


if __name__ == '__main__':
    s = Solution()
    print(s.Add(-1, 3))
