Tho*_*eia 36 python binary bit-manipulation
Python中的整数存储在两个补码中,对吗?
虽然:
>>> x = 5
>>> bin(x)
0b101
Run Code Online (Sandbox Code Playgroud)
和:
>>> x = -5
>>> bin(x)
-0b101
Run Code Online (Sandbox Code Playgroud)
那太蹩脚了.我怎么让python给我真正的二进制位数,而没有它的前面的0b?所以:
>>> x = 5
>>> bin(x)
0101
>>> y = -5
>>> bin(y)
1011
Run Code Online (Sandbox Code Playgroud)
tyl*_*erl 67
如果你提供面具,效果最好.这样你就可以指定签名扩展的距离.
>>> bin(-27 & 0b1111111111111111)
'0b1111111111100101'
Run Code Online (Sandbox Code Playgroud)
或者更一般地说:
def bindigits(n, bits):
s = bin(n & int("1"*bits, 2))[2:]
return ("{0:0>%s}" % (bits)).format(s)
>>> print bindigits(-31337, 24)
111111111000010110010111
Run Code Online (Sandbox Code Playgroud)
在基本理论中,数字的实际宽度是存储大小的函数.如果它是一个32位数字,那么负数在一组32的MSB中有1.如果它是64位值,那么有64位要显示.
但在Python中,整数精度仅限于硬件的约束.在我的电脑上,这实际上有效,但它只消耗9GB的RAM来存储x的值.任何更高的东西,我得到一个MemoryError.如果我有更多的RAM,我可以存储更大的数字.
>>> x = 1 << (1 << 36)
Run Code Online (Sandbox Code Playgroud)
那么考虑到这一点,二进制数代表-1什么?正如前面的例子所示,Python能够很好地解释数百万(甚至数十亿)的精度位.在2的补码中,符号位一直向左扩展,但在Python中没有预定义的位数; 你有多少需要.
但是你会遇到歧义:二进制1表示1,还是-1?好吧,也可能是.是否111代表7或-1?同样,它也可能是.因此,根据您的精确度,111111111代表511或者-1......两者都是如此.
Python需要一种以二进制形式表示这些数字的方法,这样它们的含义就不存在歧义.该0b前缀只是说:"这个数字是用二进制".就像0x意思是"这个数字是十六进制".所以,如果我说0b1111,我怎么知道用户是想要-1还是15?有两种选择:
选项A: 符号位
您可以声明所有数字都是有符号的,最左边的位是符号位.这意味着0b1是-1,而它0b01是1.这也意味着它0b111也是-1,而0b01117是.最后,这可能比有用更令人困惑,特别是因为大多数二进制算术无论如何都是无符号的,人们更多可能会因意外地将数字标记为否定而导致错误,因为它们不包含明确的符号位.
选项B: 符号指示
使用此选项,二进制数表示无符号,负数表示" - "前缀,就像它们在十进制中一样.这是(a)与十进制更一致,(b)与最有可能使用二进制值的方式更兼容.您无法使用其二进制补码表示来指定负数,但请记住,二进制补码是存储实现细节,而不是基础值本身的正确指示.它不应该是用户必须理解的东西.
最后,选项B最有意义.混淆较少,用户无需了解存储详细信息.
cas*_*evh 14
为了将二进制序列正确地解释为二进制补码,需要与序列相关联的长度.在处理与CPU寄存器直接对应的低级类型时,存在隐式长度.由于Python整数可以具有任意长度,因此实际上没有内部二进制补码格式.由于没有与数字相关的长度,因此无法区分正数和负数.为了消除歧义,bin()在格式化负数时包含减号.
Python的任意长度整数类型实际上使用符号幅度内部格式.逻辑运算(位移,和/或等)旨在模仿二进制补码格式.这是多个精度库的典型特征.
小智 6
这是Tylerl 答案的一个更易读的版本,例如,假设您想要-2的“二进制补码”的8 位负表示形式:
bin(-2 & (2**8-1))
Run Code Online (Sandbox Code Playgroud)
2**8 代表第九位 (256),减去 1,前面的所有位都设置为 1 (255)
对于 8 位和 16 位掩码,您可以将 (2**8-1) 替换为 0xff 或 0xffff。此后,十六进制版本的可读性会降低。
如果这还不清楚,这里是它的常规函数:
def twosComplement (value, bitLength) :
return bin(value & (2**bitLength - 1))
Run Code Online (Sandbox Code Playgroud)
The compliment of one minus number's meaning is mod value minus the positive value. So I think?the brief way for the compliment of -27 is
bin((1<<32) - 27) // 32 bit length '0b11111111111111111111111111100101'
bin((1<<16) - 27)
bin((1<<8) - 27) // 8 bit length '0b11100101'
Run Code Online (Sandbox Code Playgroud)
不确定如何使用标准库获得你想要的东西。有一些脚本和软件包可以为您进行转换。
我只是想指出“为什么”,以及为什么它并不蹩脚。
bin() 不返回二进制位。它将数字转换为二进制字符串。前导的“0b”告诉解释器您正在处理一个二进制数,根据 python 语言的定义。这样你就可以直接使用二进制数,就像这样
>>> 0b01
1
>>> 0b10
2
>>> 0b11
3
>>> 0b01 + 0b10
3
Run Code Online (Sandbox Code Playgroud)
这并不蹩脚。那太棒了。
http://docs.python.org/library/functions.html#bin
箱(x)
将整数转换为二进制字符串。
http://docs.python.org/reference/lexical_analysis.html#integers
整数和长整数文字由以下词法定义描述:
bininteger ::= "0" ("b" | "B") bindigit+
bindigit ::= "0" | 二进制数字 “1”