简体   繁体   English

python中的二进制加法程序

[英]Binary addition program in python

I am writing a binary addition program but am unsure as to why when the inputs start with a zero the output is incorect.The output is also incorrect when the program has to add zeros to the start of one of the inputs to make them the same length.我正在编写一个二进制加法程序,但不确定为什么当输入以零开头时输出不正确。当程序必须在其中一个输入的开头添加零以使它们相同时,输出也不正确长度。

a = input('Enter first binary number\t')
b = input('Enter second binary number\t')

carry = 0
answer = ""

length = (max(len(a),len(b))) - min(len(a),len(b))

if b > a:
    a = length * '0' +  a
elif a > b:
    b = length * '0' +  b

print(a)
print(b)

for i in range(len(a)-1, -1, -1):                     
    x = carry                                        
    if a[i] == '1': x += 1
    else: x = 0

    if b[i] == '1': x += 1
    else: x = 0

    if x % 2 == 1: answer = '1' + answer
    else: answer = '0' + answer

    if x < 2: carry = 0
    else: carry = 1

if carry == 1: answer = '1' + answer                    

print(answer)

What an excellent opportunity to explore some Boolean Logic.这是探索一些布尔逻辑的绝佳机会。

Adding binary like this can be done with two "half adders" and an "or"可以使用两个“半加器”和一个“或”来添加这样的二进制文件

First of all the "Half Adder" which is a XOR to give you a summed output and an AND to give you a carry.首先是“半加器”,它是一个 XOR 给你一个总和输出和一个 AND 给你一个进位。

在此处输入图片说明

[EDIT as per comments: python does have an XOR implemented as ^ but not as a "word" like and not or . [根据评论编辑:python 确实有一个 XOR 实现为^但不是作为“单词” like and not or I am leaving the answer as is, due to the fact it is explaining the Boolean logic behind a binary add]我将答案保持原样,因为它正在解释二进制加法背后的布尔逻辑]

As python doesn't come with a XOR, we will have to code one.由于 python 没有 XOR,我们将不得不编写一个。 XOR itself is two AND's (with reversed inputs) and an OR, as demonstrated by this: XOR 本身是两个 AND(具有反向输入)和一个 OR,如下所示:

在此处输入图片说明

This would result is a simple function, like this:这将导致一个简单的函数,如下所示:

def xor(bit_a, bit_b):
    A1 = bit_a and (not bit_b)
    A2 = (not bit_a) and bit_b
    return int(A1 or A2)

Others may want to write this as follows:其他人可能想这样写:

def xor(bit_a, bit_b):
    return int(bit_a != bit_b)

which is very valid, but I am using the Boolean example here.这是非常有效的,但我在这里使用布尔示例。

Then we code the "Half Adder" which has 2 inputs (bit_a, bit_b) and gives two outputs the XOR for sum and the AND for carry:然后我们对“半加器”进行编码,它有 2 个输入(bit_a,bit_b),并给出两个输出的和的异或和进位的与:

def half_adder(bit_a, bit_b):
    return (xor(bit_a, bit_b), bit_a and bit_b)

so two "Half Adders" and an "OR" will make a "Full Adder" like this:所以两个“半加器”和一个“或”将形成一个“全加器”,如下所示:

在此处输入图片说明

As you can see, it will have 3 inputs (bit_a, bit_b, carry) and two outputs (sum and carry).如您所见,它将有 3 个输入(bit_a、bit_b、进位)和两个输出(和和进位)。 This will look like this in python:这在 python 中看起来像这样:

def full_adder(bit_a, bit_b, carry=0):
    sum1, carry1 = half_adder(bit_a, bit_b)
    sum2, carry2 = half_adder(sum1, carry)
    return (sum2, carry1 or carry2)

If you like to look at the Full Adder as one logic diagram, it would look like this:如果您喜欢将全加器视为一个逻辑图,它看起来像这样:

在此处输入图片说明

Then we need to call this full adder, starting at the Least Significant Bit (LSB), with 0 as carry, and work our way to the Most Significant Bit (MSB) where we carry the carry as input to the next step, as indicated here for 4 bits:然后我们需要调用这个全加器,从最低有效位 (LSB) 开始,以 0 作为进位,然后工作到最高有效位 (MSB),我们将进位作为下一步的输入,如下所示这里是 4 位:

在此处输入图片说明

This will result is something like this:这将是这样的结果:

def binary_string_adder(bits_a, bits_b):
    carry = 0
    result = ''
    for i in range(len(bits_a)-1 , -1, -1):
        summ, carry = full_adder(int(bits_a[i]), int(bits_b[i]), carry)
        result += str(summ)
    result += str(carry)
    return result[::-1]

As you see we need to reverse the result string, as we built it up "the wrong way".如您所见,我们需要反转result字符串,因为我们以“错误的方式”构建它。

Putting it all together as full working code:将它们放在一起作为完整的工作代码:

# boolean binary string adder

def rjust_lenght(s1, s2, fill='0'):
    l1, l2 = len(s1), len(s2)
    if l1 > l2:
        s2 = s2.rjust(l1, fill)
    elif l2 > l1:
        s1 = s1.rjust(l2, fill)
    return (s1, s2)

def get_input():
    bits_a = input('input your first binary string  ')
    bits_b = input('input your second binary string ')
    return rjust_lenght(bits_a, bits_b)

def xor(bit_a, bit_b):
    A1 = bit_a and (not bit_b)
    A2 = (not bit_a) and bit_b
    return int(A1 or A2)

def half_adder(bit_a, bit_b):
    return (xor(bit_a, bit_b), bit_a and bit_b)

def full_adder(bit_a, bit_b, carry=0):
    sum1, carry1 = half_adder(bit_a, bit_b)
    sum2, carry2 = half_adder(sum1, carry)
    return (sum2, carry1 or carry2)

def binary_string_adder(bits_a, bits_b):
    carry = 0
    result = ''
    for i in range(len(bits_a)-1 , -1, -1):
        summ, carry = full_adder(int(bits_a[i]), int(bits_b[i]), carry)
        result += str(summ)
    result += str(carry)
    return result[::-1]

def main():
    bits_a, bits_b = get_input()
    print('1st string of bits is : {}, ({})'.format(bits_a, int(bits_a, 2)))
    print('2nd string of bits is : {}, ({})'.format(bits_b, int(bits_b, 2)))
    result = binary_string_adder(bits_a, bits_b)
    print('summarized is         : {}, ({})'.format(result, int(result, 2)))

if __name__ == '__main__':
    main()

two internet sources used for the pictures:用于图片的两个互联网资源:

For fun, you can do this in three lines, of which two is actually getting the input:为了好玩,你可以用三行来做这件事,其中两行实际上是获取输入:

bits_a = input('input your first binary string  ')
bits_b = input('input your second binary string ')
print('{0:b}'.format(int(bits_a, 2) + int(bits_b, 2)))

And in your own code, you are throwing away a carry if on second/subsequent iteration one of the bits are 0, then you set x = 0 which contains the carry of the previous itteration.在您自己的代码中,如果在第二次/后续迭代中,其中一位为 0,则您将丢弃进位,然后设置x = 0 ,其中包含前一次迭代的进位。

this is how i managed to complete this, hope you find this useful.这就是我设法完成它的方式,希望你觉得这有用。

#Binary multiplication program.
def binaryAddition(bin0, bin1):
    c = 0
    answer = ''

    if len(bin0) > len(bin1):
        bin1 = (len(bin0) - len(bin1))*"0" + bin1

    elif len(bin1) > len(bin0):
        bin0 = (len(bin1) - len(bin0))*"0" + bin0  

    #Goes through the binary strings and tells the computer what the anser should be.
    for i in range(len(bin0)-1,-1,-1):
        j = bin0[i]
        k = bin1[i]
        j, k = int(j), int(k)

        if k + j + c == 0:
            c = 0
            answer = '0' + answer
        elif k + j + c == 1:
            c = 0
            answer = '1' + answer
        elif k + j + c == 2:
            c = 1
            answer = '0' + answer
        elif k + j + c == 3:
            c = 1
            answer = '1' + answer
        else:
            print("There is something wrong. Make sure all the numbers are a '1' or a '0'. Try again.") #One of the numbers is not a 1 or a 0.
            main()

    return answer


def binaryMultiplication(bin0,bin1):
    answer = '0'*8
    if len(bin0) > len(bin1):
        bin1 = (len(bin0) - len(bin1))*"0" + bin1

    elif len(bin1) > len(bin0):
        bin0 = (len(bin1) - len(bin0))*"0" + bin0

    for i in range(len(bin0)-1,-1,-1):
        if bin1[i] == '0':
            num = '0'*len(answer)
        elif bin1[i] == '1':
            num = bin0 + '0'*((len(bin0)-1)-i)
        answer = binaryAddition(num, answer)
    print(answer)


def main():
    try:
        bin0, bin1 = input("Input both binary inputs separated by a space.\n").split(" ")
    except:
        print("Something went wrong. Perhaps there was not a space between you numbers.")
        main()

    binaryMultiplication(bin0,bin1)

    choice = input("Do you want to go again?y/n\n").upper()
    if choice == 'Y':
        main()
    else: input()

main()

The following adds integers i1 and i2 using bitwise logical operators (i1 and i2 are overwritten).下面使用按位逻辑运算符将整数 i1 和 i2 相加(覆盖 i1 和 i2)。 It computes the bitwise sum by i1 xor i2 and the carry bit by (i1 & i2)<<1.它通过 i1 xor i2 计算按位和,通过 (i1 & i2)<<1 计算进位。 It iterates until the shift register is empty.它迭代直到移位寄存器为空。 In general this will be a lot faster than bit-by-bit一般来说,这将比逐位快得多

while i2:                               # check shift register != 0
    i1, i2 = i1^i2, (i1&i2) << 1        # update registers

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM