首页 > 解决方案 > Python中的二进制加法进位和溢出

问题描述

我正在尝试构建一个计算 8 位数组中四个元素的校验和的函数。我正在努力解决的是二进制加法的进位和溢出。例如:

    101
    +
    101
    ----
   1010

它溢出了,我们用最右边的最左边环绕,所以它变成了 011。

我可以使用bin进行计算。如果最右边的值为 0,最左边的值为 1,我可以执行上述操作,因为在这种情况下,我们不必将任何东西从右边带到下一个值。

我正在努力解决的是,类似这种情况:

    111
    +
    110
    ----
   1101

它再次溢出,但这次我们必须环绕1(最左边)+1(最右边) = 10,这意味着在这种情况下,我们将取0并将1带到下一个最右边(0)。在这种情况下,最终结果将是 = 110

如果它是1而不是0 ,我们将再次得到10,我们必须将 1 带入下一个值,依此类推。

请参阅下面的代码:

def overFlow(sumN):  
  # this works if my left most is 1 and my right most is 0
  if(sumN[8] == "0"):
    print("--------------------")
    overflow = bin(int(sumN[0],2) + int(sumN[8],2))[2:]
    temp = list(sumN)
    temp.pop(0)
    temp.pop(7)
    temp.append(overflow)
    newtemp= ""
    for i in temp:
      newtemp += i  
    sumN = newtemp
    print(sumN)
    print("--------------------")
  # else:
  # this is where I am stuck

  return sumN

def checksum(message):
  var1 = message[0][2:]
  var2 = message[1][2:]
  var3 = message[2][2:]
  var4 = message[3][2:]
  bit_len = 8
  print(len(var1))

  sum1 = bin(int(var1,2) + int(var2,2))[2:]
  if(len(sum1) > bit_len):
    sum1 = overFlow(sum1)
  print("var 1  " +var1+"\nvar 2  "+var2+"\nSum    "+sum1)
  sum2 = bin(int(sum1,2) + int(var3,2))[2:]
  if(len(sum2) > bit_len):
    sum2 = overFlow(sum2)
  print("var 1  " +sum1+"\nvar 2  "+var3+"\nSum    "+sum2)
  sum3 = bin(int(sum2,2) + int(var4,2))[2:]
  if(len(sum3) > bit_len):
    sum3 = overFlow(sum3)
  print("var 1  " +sum2+"\nvar 2  "+var4+"\nSum    "+sum3)
  comp = ""
  tot_sum = sum3
  n = len(tot_sum)
  for i in range(n):
    if (tot_sum[i]== '0'):
      comp+= '1';
    if (tot_sum[i]== '1'):
      comp+= '0';
  
  print(f"1's complement is = {comp}")

message = ['0b10110110','0b11011100','0b01100111','0b01111101']
checksum(message);

任何帮助深表感谢。

更新:上述消息的正确输出应如下所示:

var1  10110110
var2  11011100
sum1 110010010 "overflow so we take left most and add it with right most" 1+0 = 1
sum1 becomes = 10010011

sum1  10010011
var3  01100111
sum3  11111010 "no overflow, so we do nothing"

sum3  11111010
var4  01111101
     101110111 "overflow left most(1) + right most (1) = 10" we take zero and carry one to the next right most number
        which is 1 which will give me again 10 so we take zero and carry one until we don't have to carry anymore
the final result should be **01110000** 
after 1's compelement it should be **10001111**

这是我当前的输出:

var 1  10110110
var 2  11011100
Sum    10010011
var 1  10010011
var 2  01100111
Sum    11111010
var 1  11111010
var 2  01111101
Sum    101110111
1's complement or the checksum is = 010001000

标签: pythonpython-3.x

解决方案


这是一个简单的 8 位校验和例程,带有翻转功能。有一个包装函数接受并返回原始 ascii 二进制格式的数据。但是您真的只想使用 bin 数组和第一个函数。

def checksum(bin_array):
    result = 0
    for num in bin_array:
        result += num
        if result >= 256:
            result -=255 # subtract 256 and add one
        # print(bin(result)) # show partial result if desired
    return result

def checksum_binstrs(ascii_bin_array):
    bin_array = list(map(lambda x: int(x,2),ascii_bin_array)) # convert to binary array
    result = checksum(bin_array)
    return bin(result) # convert to binary string


message = ['0b10110110','0b11011100','0b01100111','0b01111101']

print (checksum_binstrs(message))

推荐阅读