这个替代的按位运算符函数有什么问题?

What is wrong with this alternative bitwise operator function?

n1 = "0b1110"
n2 = "0b101"

def bitwise_or(num1, num2):
    diff1 = ""
    new_num1 = []
    new_num2 = []
    new_num = []
    for c in num1:
        new_num1.append(c)
    for c in num2:
        new_num2.append(c)
    if len(num1) != len(num2):
        if len(num1) > len(num2):
            diff1 = "0" * (len(num1) - len(num2))
            for c in diff1:
                new_num2.append(c)
        if len(num1) < len(num2):
            diff1 = "0" * (len(num2) - len(num1))
            for c in diff1:
                new_num1.append(c)
    for i in range(len(new_num1)):
        if new_num1[i] == "1" or new_num2[i] == "1":
            new_num.append("1")
        else:
            new_num.append(new_num1[i])
    final = "".join(new_num)
    return final

print(bitwise_or(n1,n2))

我做了一个应该复制|的函数操作,但它不能正常工作。正确答案应该是打印出 0b1111,但我不明白它是怎么得到的。

当您填充零时,您应该将它们插入之前数字的位。

0b1表示数字1。如果您尝试使用 0b11101 或它,则无法将其更改为 0b10000 您必须将其填充为 0b00001.

您对 0b 的处理也有效,但不清楚,不可读。它只是 "happen" 工作,因为当你循环遍历 0b111010b00001 时,第一个字符在两者中都是 0 所以你最终在 new_num.append(new_num1[0]) 然后 b != '1' 因此 if 测试失败并且 b 被插入 new_num.

我建议你把开头的前缀去掉,在末尾加上。这也稍微简化了正确的填充。


顺便说一句:要将字符串转换为字符列表,您只需对其调用 list

new_num1 = list(num1)

此外,要将一定数量的元素添加到列表中,您可以使用 extend 方法,或者您可以使用切片赋值:

>>> my_list = list('hello')
>>> my_list
['h', 'e', 'l', 'l', 'o']
>>> my_list.extend('world')
>>> my_list
['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd']

所以你的代码会变成这样:

def bitwise_or(num1, num2):
    new_num1 =list(num1)
    new_num2 = list(num2)
    if len(num1) > len(num2):
        new_num2[2:2] = '0' * (len(num1) - len(num2))
    elif len(num1) < len(num2):
        new_num1[2:2] = '0' * (len(num2) - len(num1))

    new_num = []
    for c1, c2 in zip(new_num1, new_num2):
        if c1 == "1" or c2 == "1":
            new_num.append("1")
        else:
            new_num.append(c1)
    return ''.join(new_num)

但是我宁愿明确处理前缀:

def bitwise_or(num1, num2):
    new_num1 =list(num1[2:])
    new_num2 = list(num2[2:])
    if len(num1) > len(num2):
        new_num2[:0] = '0' * (len(num1) - len(num2))
    elif len(num1) < len(num2):
        new_num1[:0] = '0' * (len(num2) - len(num1))

    new_num = []
    for c1, c2 in zip(new_num1, new_num2):
        if c1 == "1" or c2 == "1":
            new_num.append("1")
        else:
            new_num.append(c1)
    return '0b' + ''.join(new_num)

您使用的方法有点复杂,但是您的代码中的错误是您在长度不同的情况下用零填充了右侧。在给定的情况下,你得到的 0b101 变成了 0b1010,它与 0b1110 的或运算给出了你最终得到的结果。左补二进制数,即0b101变为0b0101。此代码有效

n1 = "0b1110"
n2 = "0b101"

def bitwise_or(num1, num2):
    new_num1 = []
    new_num2 = []
    new_num = []

    for c in num1[2:]:
        new_num1.append(c)

    for c in num2[2:]:
        new_num2.append(c)

    if len(num1) != len(num2):
        if len(num1) > len(num2):
            diff1 = ["0"] * (len(num1) - len(num2))
            new_num2 = diff1 + new_num2
        if len(num1) < len(num2):
            diff1 = ["0"] * (len(num2) - len(num1))
            new_num1 = diff1 + new_num1
    for i in range(len(new_num1)):
        if new_num1[i] == "1" or new_num2[i] == "1":
            new_num.append("1")
        else:
            new_num.append(new_num1[i])
    final = "".join(new_num)
    return final


print(bitwise_or(n1, n2))

我建议将您的二进制数(跳过“0b”前缀)转换为整数列表,然后一点一点地应用 OR 逻辑运算符。您也可以尝试列出理解,例如

new_num1 = [int(i) for i in n1[2:]]

和外部函数(您也可以在另一个函数中定义,例如左边填充较短数字的函数。

这是我的优化版本。不一定要这样做,但可以将其视为探索 Python 功能的灵感。顺便说一句,它可以处理任意数量的输入参数,但可能(?)只能在 Python 3 上工作,尽管...

def format_binary_string(bin_string, length, prefix=""):
    return "{}{:0{}b}".format(prefix, int(bin_string, 2), length)

def bitwise_or(*numbers):
    max_length = max(len(n) for n in numbers)
    bits = [format_binary_string(n, max_length, "") for n in numbers]

    new_bits = ["1" if "1" in bs else "0" for bs in zip(*bits)]
    return "".join(new_bits)


n1 = "0b1110"
n2 =  "0b101"
print(bitwise_or(n1, n2))