如何在 python3 中将负位表示的数字转换为其实际的负 int 值?

d_d*_*ric 2 python algorithm bit-manipulation bit python-3.x

你好,我已经解决了这个 leetcode 问题https://leetcode.com/problems/single-number-ii。目标是在 O(n) 时间和 0(1) 空间内解决问题。我写的代码如下:

class Solution:
    def singleNumber(self, nums: List[int]) -> int:
        counter = [0 for i in range(32)]
        result = 0
        for i in range(32):
            for num in nums:
                if ((num >> i) & 1):
                    counter[i] += 1
            result = result | ((counter[i] % 3) << i)
        return self.convert(result)
        #return result

    def convert(self,x):
        if x >= 2**31:
            x = (~x & 0xffffffff) + 1
            x = -x
        return x
Run Code Online (Sandbox Code Playgroud)

现在有趣的部分是在convert函数中,因为Python使用对象来存储int而不是32位字或其他东西,所以当my的MSBcounter设置为1时,它不知道结果是否为负。我通过转换它来处理它其 2 的补码并返回负值。

现在其他人发布了他们的解决方案:

def convert(self, x):
    if x >= 2**31:
        x -= 2**32
    return x 
Run Code Online (Sandbox Code Playgroud)

我不明白为什么会这样。我需要帮助理解为什么这种减法有效。

Mar*_*nen 5

无符号n 位数字的最高位的值为2 n-1

有符号二进制补码 n 位数字的最高位的值为-2 n-1

这两个值之间的2 n

因此,如果无符号 n 位数字设置了最高位,则要转换为二进制补码有符号数,请减去2 n

在 32 位数字中,如果设置了第 31 位,则该数字将 >= 2 31,因此公式为:

if n >= 2**31:
    n -= 2**32
Run Code Online (Sandbox Code Playgroud)

我希望这能够清楚地表明这一点。