提问人:Parth 提问时间:2/19/2023 最后编辑:Parth 更新时间:2/21/2023 访问量:250
使用位操作了解 python 中的二进制加法
Understanding binary addition in python using bit manipulation
问:
我正在寻找这个问题的解决方案:
给定两个整数 和 ,返回两个整数之和,而不使用运算符 和 。(输入限制:<= a, b <=
a
b
+
-
-1000
1000
)
在所有这些解决方案中,我都在努力理解为什么这些解决方案在评估时超过最大 32 位时会这样做 [请参阅下面的代码]。~(a ^ mask)
a
0x7fffffff
a + b
def getSum(self, a: int, b: int) -> int:
# 32bit mask
mask = 0xFFFFFFFF # 8Fs = all 1s for 32 bits
while True:
# Handle addition and carry
a, b = (a ^ b) & mask, ((a & b) << 1) & mask
if b == 0:
break
max_int = 0x7FFFFFFF
print("A:", a)
print("Bin A:", bin(a))
print("Bin M:", bin(mask))
print(" A^M:", bin(a ^ mask))
print("~ A^M:", bin(~(a ^ mask)))
print(" ~ A:", bin(~a))
return a if a < max_int else ~(a ^ mask)
我不明白为什么我们在返回答案时需要再次掩码?a
退出循环时,它已经被屏蔽了:。那么,如果设置为 for,为什么我们不能这样做呢?a = (a ^ b) & mask
~a
32nd bit
1
a
我看了 Python 中 Bit-wise NOT 的含义,理解了 ~ 操作,但没有明白。
的输出 、 。正确返回:a = -12
b = -8
-20
A: 4294967276
Bin A: 0b11111111111111111111111111101100
Bin M: 0b11111111111111111111111111111111
A^M: 0b10011
~ A^M: -0b10100
~ A: -0b11111111111111111111111111101101
答:
您忘记指定原始问题的约束,即 和 在 [-1000, 1000] 中。该代码是 C 或 Java 实现的端口,它假定并且是 4 字节签名整数。而且我不确定你是否正确理解和代码。前者添加第 i 位,并忽略每个位的进位。后者获得所有被忽略的进位。a
b
a
b
(a ^ b)
(a & b) << 1
a
b
要点是,最后一个操作是处理负整数。反转 的下 32 位并保留其他上位。因此,结果的按位 NOT 保留了 的下 32 位,并反转了其他上位。因为 的上位(下 32 位除外)都为零,所以只是将所有上位设置为 1。它相当于 ,可读性更强。~(a ^ mask)
a ^ mask
a
~(a ^ mask)
a
a
~(a ^ mask)
a | ~mask
请参阅以下示例。
print(~(0xffffffff ^ 0xffffffff)) # This will output -1.
print(~(0xfffffffe ^ 0xffffffff)) # This will output -2.
print(~0xffffffff) # This will output -4294967296(-0x100000000).
评论
^
a | ~mask
a ^ mask
~(a ^ mask)
a | ~mask
a ^ mask
~(a^ mask)
a | ~mask
这里有一个有用的链接 - 区分 2 的补码负数和相应的正数。
由于边界,我们永远不会有正数溢出。(数字仅在 [-1000, 1000] 之间)。所以我们知道,当设置第 32 位时,它是因为它是一个负数。
请注意,如果我们的范围也允许正数加法溢出,那么就无法区分正数设置第 32 位和负数设置。
因此,我们保留 直到前 32 位的位,并向其添加无限前导 1,以便 Python 知道这是一个负数。~(a ^ mask)
a
如果你看一下,它已经是 -20 的 2s 补码表示。但现在 Python 将其视为正数。因此,我们需要告诉 Python 使用 .Bin A
~(a ^ mask)
评论
a
a.__add__(b)
math.log(math.exp(a) * math.exp(b))
a
从技术上讲,不是无符号的。Python 中的所有整数都是有符号的,但它是一个正值,因为你从不做任何事情来使它为负数。如果您使用的是具有 32 位整数的语言,则设置位 31 会使其为负数。这在 Python 中不会发生。我可以根据需要添加任意数量的位,并且它将保持为正数。我们看不到符号位,我们无法设置符号位。