python

时间:2018-12-05 06:55:50

标签: python integer unsigned twos-complement fixed-point

我正在尝试模拟定点滤波器的实现。我想捕获2s补体环绕/溢出和固定寄存器宽度之类的低级硬件功能。某些寄存器的宽度由硬件功能设置为不寻常且较长的宽度(即72b)。

我在使用内置整数方面取得了一些进展。无限宽度非常有用...但是我发现自己与Python进行了很多斗争,因为它有时想将二进制解释为正整数,有时似乎想将非常相似的二进制解释为负2的补码。例如:

>> a = 0b11111                          # sign-extended -1
>> b = 0b0011
>> print("{0:b}".format(a*b))
5f
>> print("{0:b}".format((a*b)&a))       # Truncate to correct product length
11101                                   # == -3 in 2s complement. Great!
>> print("{0:b}".format(~((a*b)&a)+1))  # Actually perform the 2's complement
-11101                                  # Arrrrggggghhh
>> print("{0:b}".format((~((a*b)&a)&a)+1))  # Truncate with extreme prejudice
11                                          # OK. Fine.

我想如果我想得足够认真的话,我就能弄清楚为什么所有这些方法都可以做到这一点,但是如果我可以在无符号空间中完成所有操作而不必担心python添加符号位,那么事情将会变得更加轻松,并且出错更少-易于。有人知道是否有相对简单的方法吗?我考虑了位字符串,但是在此应用程序中我必须做很多加法和乘法运算,并且内置整数算法对此非常有用。

1 个答案:

答案 0 :(得分:0)

~x实际上是在任意精度整数上定义为-(x+1)的。它不做位算术:~0255的一个字节整数,65535是两个字节的整数,1023代表10位整数,等等。因此通过对可拉伸整数进行位反转来定义~是没有用的。

如果a定义了整数的固定宽度(其中0b11111表示您正在使用5位数字),则位求反就和a^x一样简单。

print("{0:b}".format(a ^ b)
# => 11100

同时使用“ a+1-b”或“ a^b+1”最容易实现互补:

print("{0:b}".format((a + 1) - b))
# => 11101
print("{0:b}".format((a ^ b) + 1))
# => 11101

tl; dr:如果您想保持未签名状态,请不要使用~