【问题标题】:Binary addition carry and overflow in PythonPython中的二进制加法进位和溢出
【发布时间】:2020-11-25 12:12:20
【问题描述】:

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

    101
    +
    101
    ----
   1010

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

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

我正在苦苦挣扎的是,类似这种情况:

    111
    +
    110
    ----
   1101

它再次溢出,但这次我们必须环绕 1(left most)+1(right most) = 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

【问题讨论】:

  • 请提供预期的MRE。显示中间结果与预期结果的偏差。我们应该能够将您的代码块粘贴到文件中,运行它并重现您的问题。这也让我们可以在您的上下文中测试任何建议。
  • 你已经有代码了。跟踪执行(通常使用战略性放置的print 语句完成)。您的环绕代码与您的预期有何不同?
  • 只需将溢出的数字切割成2个数字,1是1个字符(溢出),另一个是8个字符,并像处理2个8字符二进制数一样对待这些数字。重复这个环绕直到你没有溢出
  • 去掉分号,用于补码string.translate
  • 18行代码的结果是1's complement is = 0000111

标签: python python-3.x


【解决方案1】:

这是一个简单的 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))

【讨论】:

  • 啊我看着我的代码感觉很糟糕。我看到你是怎么处理这个的,我没有那样想。感谢您的宝贵时间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-31
  • 1970-01-01
  • 2015-09-25
  • 2021-10-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多