Python:16位补充加法实现

时间:2015-04-24 08:23:56

标签: python ones-complement

我在python中实现了16位整数的补充,但是我试图看看是否有更好的方法来实现它。

 # This function returns a string of the bits (exactly 16 bits)
 # for the number (in base 10 passed to it)
 def get_bits(some_num):
        binar = bin(some_num)[2::]
        zeroes = 16 - len(binar)
        padding = zeroes*"0"
        binar = padding + binar
        return binar


# This function adds the numbers, and handles the carry over
# from the most significant bit
def add_bits(num1, num2):
        result = bin(int(num1,2) + int(num2,2))[2::]
        # There is no carryover
        if len(result) <= 16 :
                result = get_bits(int(result,2))
        # There is carryover
        else :
                result = result[1::]
                one = '0000000000000001'
                result = bin(int(result,2) + int(one,2))[2::]
                result = get_bits(int(result,2))
        return result

现在运行它的一个例子是:

print add_bits("1010001111101001", "1000000110110101")

返回:

0010010110011111

结果是什么写得安全(注意我在这里没有做任何否定,因为那部分是微不足道的,我对中间步骤更感兴趣)?有更好的pythonic方式吗? 谢谢你的帮助。

2 个答案:

答案 0 :(得分:3)

在字符串和整数之间来回转换以进行数学运算是低效的。以整数进行数学运算并使用格式显示二进制:

MOD = 1 << 16

def ones_comp_add16(num1,num2):
    result = num1 + num2
    return result if result < MOD else (result+1) % MOD

n1 = 0b1010001111101001
n2 = 0b1000000110110101
result = ones_comp_add16(n1,n2)

print('''\
  {:016b}
+ {:016b}
------------------
  {:016b}'''.format(n1,n2,result))

输出:

  1010001111101001
+ 1000000110110101
------------------
  0010010110011111

答案 1 :(得分:1)

在数字之间来回转换,一位字符串列表和字符串可能并不像是一种非常Pythonic的入门方式。

更具体地说,使用bin(i)[2:]将int转换为位序列非常容易。无论如何,它可能是值得做的(例如,因为它比数字化更简洁或更有效),但即使它是,最好将它包装在一个以它的功能命名的函数中(并且可能甚至添加一条评论,解释你为什么这样做。)

你也在那里得到了不必要的复杂代码。例如,要执行此操作,请执行以下操作:

one = '0000000000000001'
result = bin(int(result,2) + int(one,2))[2::]

但是你知道int(one,2)只是数字1,除非你搞砸了,所以为什么不使用1,这更短,更易读,更明显,并删除任何搞砸的机会?

你并没有遵循PEP 8风格。

所以,坚持你的基本设计&#34;使用字符串作为位,只使用从Python 1.5到3.5而不是format不变的基本字符串操作,并进行基本添加整数而不是比特&#34;,我写这样的东西:

def to_bits(n):
    return bin(n)[2:]

def from_bits(n):
    return int(n, 2)

def pad_bits(b, length=16):
    return ["0"*length + b][-length:]

def add_bits(num1, num2):
    result = to_bits(from_bits(num1) + from_bits(num2))
    if len(result) <= 16: # no carry
        return pad_bits(result)
    return pad_bits(to_bits(from_bits(result[1:]) + 1))

但更好的解决方案是完全抽象出字符串表示。构建一个知道如何像整数一样行动的类,但也知道如何像一个位序列那样行事。或者只是在PyPI上找到一个。然后你的代码变得微不足道。例如:

from bitstring import BitArray

def add_bits(n1, n2):
    """
    Given two BitArray values of the same length, return a BitArray
    of the same length that's the one's complement addition.
    """
    result = n1.uint + n2.uint
    if result >= (1 << n1.length):
        result = result % n1.length + 1
    return BitArray(uint=result, length=n1.length)

我不确定bitstring实际上是您正在做的事情的最佳模块。 PyPI上有六个不同的位操作库,所有这些库都有不同的接口和不同的优点和缺点;我刚刚选择了第一个在搜索中出现并使用它实现了一个实现。