我在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方式吗? 谢谢你的帮助。
答案 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上有六个不同的位操作库,所有这些库都有不同的接口和不同的优点和缺点;我刚刚选择了第一个在搜索中出现并使用它实现了一个实现。