在Python中查找数字的补码

6g8kf2rb  于 2023-01-06  发布在  Python
关注(0)|答案(7)|浏览(144)

我试图在Python中找到一个数的补码。我知道有其他的解决方案,但我试图自己做。我的第一次尝试:

def findComplement(self, num):
    """
    :type num: int
    :rtype: int
    """
    numb = str(num)
    i = 0
    while(i<=len(numb)):
        if numb[i] == "0":
            numb[i] = "1"
        else:
            numb[i] = "0"
        i=i+1
    return int(numb)

但字符串是不可变的,所以它给了一个错误,我的第二次尝试:

def findComplement(self, num):
    """
    :type num: int
    :rtype: int
    """
    numb = str(num)
    numb2 = []
    k =0
    for j in numb:
        numb2[k] = j #error on this line
        k=k+1
    i = 0
    while(i<=len(numb2)):
        if numb2[i] == "0":
            numb2[i] = "1"
        else:
            numb2[i] = "0"
        i=i+1
    return int(numb2)

程序2出错:

Line 11: IndexError: list assignment index out of range
hjzp0vay

hjzp0vay1#

由于其他答案涵盖了您的主要问题,您也可以只使用字典将1Map到0,反之亦然:

>>> d = {'0': '1', '1': '0'}
>>> s = '0101'
>>> ''.join(d[x] for x in s)
'1010'
icomxhvb

icomxhvb2#

所以我想自己找到一个数的二进制补码,但是不满意掩码是如何生成的,还有其他的东西,因为它们涉及到使用二进制数的字符串表示。
所以我深入挖掘了一下,发现了这个reddit post,他们通过逐位移位生成了掩码。
我还发现你可以用int.bit_lenght(<your_number>)来计算整数的位数,而不用len(bin(<your-number>)[2:]),唯一的问题是:它对数字0返回0,所以你必须考虑到这一点。
虽然我不知道与字符串操作相比,什么方法更有性能,是否值得。
但最后这是我的最终解决方案,我发现它很简洁,因为它不涉及字符串。

def bin_complement(num, on_two=False, bit_count=0):
    """
    num(int) dezimal number
    on_two(bool) complement on 2 else on 1
    bit_count = number of bits for the mask, defaults to bits in num
    returns(int) complementary number
    """
    bit_count = max(bit_count, num.bit_length(), 1)
    mask = 2 ** bit_count - 1
    complement = num ^ mask
    if on_two:
        complement += 1
    return complement

编辑:2**bit_count - 1是一种更快的方式

for _ in range(bit_count):
    mask <<= 1
    mask |= 1

Edit 2:如果你想取定长位数的补码。
例如:C_1(0001)-〉0001异或1111 = 1110,而不只是0000。
现在,您可以为掩码设置bit_count值,以使补码正确工作。

tpgth1q7

tpgth1q73#

你有一些问题。
首先,你没有正确地将输入转换成二进制字符串,这可以通过numb = bin(num)[2:]而不是num = str(num)来完成。
第二,你试图索引你的空numb2列表,实际上没有必要创建一个单独的numb2列表,你可以直接操作你的numb字符串,就像你第一次尝试的那样。例如:

for i in range(len(numb)):
    if numb[i] == "0":
        numb[i] = "1"
    else:
        numb[i] = "0"

最后,要将二进制字符串转换回int,应该执行int(numb, 2)而不是int(numb)

mlnl4t2r

mlnl4t2r4#

numb2是一个空列表。它没有任何要寻址(和更新)的元素。您需要的是一个bytearray,而不是一个list(或string):

def findComplement(self, num):
    """
    :type num: int
    :rtype: int
    """
    numb = bytearray(str(num), 'utf-8')
    i = 0
    while(i<len(numb)):
        if numb[i] == ord("0"):
            numb[i] = ord("1")
        else:
            numb[i] = ord("0")
        i=i+1
    return int(numb)

可以看出,这需要一些其他的小改动,因为bytearray中存储的数据是字节(0-255)而不是字符。解决方案是使用ord函数,从"0""1"获取字节数。此外,还有一个小问题(减一)。由于索引和计数从零开始,i应该严格小于字符串的长度。
我还想补充一点,虽然有更简单的方法来实现0和/或1的补码。

rkttyhzu

rkttyhzu5#

假设我们必须找到101的补码,如果我们将输入与掩码111进行异或,则我们将得到010,它是补码。

def findComplement(self, num: int) -> int:
        mask_len=len(bin(num))-2
        mask=int("1"*mask_len,2)
        return mask^num
5us2dqdw

5us2dqdw6#

对于那些寻找一行程序的人,这里有一个:

int(bin(value)[2:].rjust(numbits, '0').translate(str.maketrans('01', '10')), 2)

上面的代码计算numbits位二进制数value的1的补码:
当然,我们可以将其转换为函数:

def onescomplement(value, numbits):
    return int(bin(value)[2:].rjust(numbits, '0').translate(str.maketrans('01', '10')), 2)

高温加热

zqdjd7g9

zqdjd7g97#

你指的不是~运算符吗,例如:

def findComplement(self, num):
    return ~num

相关问题