Python中的二进制补码?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12946116/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Two's Complement Binary in Python?
提问by Thor Correia
Integers in Python are stored in two's complement, correct?
Python中的整数以二进制补码存储,对吗?
Although:
虽然:
>>> x = 5
>>> bin(x)
0b101
And:
和:
>>> x = -5
>>> bin(x)
-0b101
That's pretty lame. How do I get python to give me the numbers in REAL binary bits, and without the 0b infront of it? So:
真是太蹩脚了。我如何让 python 给我真正的二进制位的数字,并且没有前面的 0b ?所以:
>>> x = 5
>>> bin(x)
0101
>>> y = -5
>>> bin(y)
1011
采纳答案by Jonathan Vanasco
Not sure how to get what you want using the standard lib. There are a handful of scripts and packages out there that will do the conversion for you.
不确定如何使用标准库获得您想要的东西。有一些脚本和包可以为您进行转换。
I just wanted to note the "why" , and why it's not lame.
我只是想指出“为什么”,以及为什么它不蹩脚。
bin() doesn't return binary bits. it converts the number to a binary string. the leading '0b' tells the interpreter that you're dealing with a binary number , as per the python language definition. this way you can directly work with binary numbers, like this
bin() 不返回二进制位。它将数字转换为二进制字符串。根据python语言定义,前导'0b'告诉解释器您正在处理一个二进制数。这样你就可以直接使用二进制数,就像这样
>>> 0b01
1
>>> 0b10
2
>>> 0b11
3
>>> 0b01 + 0b10
3
that's not lame. that's great.
那不是蹩脚的。那太棒了。
http://docs.python.org/library/functions.html#bin
http://docs.python.org/library/functions.html#bin
bin(x)
Convert an integer number to a binary string.
箱(x)
将整数转换为二进制字符串。
http://docs.python.org/reference/lexical_analysis.html#integers
http://docs.python.org/reference/lexical_analysis.html#integers
Integer and long integer literals are described by the following lexical definitions:
bininteger ::= "0" ("b" | "B") bindigit+
bindigit ::= "0" | "1"
整数和长整数文字由以下词法定义描述:
bininteger ::= "0" ("b" | "B") bindigit+
二进制数字 ::= "0" | “1”
回答by user1245262
回答by tylerl
It works best if you provide a mask. That way you specify how far to sign extend.
如果您提供口罩,效果最佳。这样你就可以指定符号扩展的范围。
>>> bin(-27 & 0b1111111111111111)
'0b1111111111100101'
Or perhaps more generally:
或者更一般地说:
def bindigits(n, bits):
s = bin(n & int("1"*bits, 2))[2:]
return ("{0:0>%s}" % (bits)).format(s)
>>> print bindigits(-31337, 24)
111111111000010110010111
In basic theory, the actual width of the number is a function of the size of the storage. If it's a 32-bit number, then a negative number has a 1 in the MSB of a set of 32. If it's a 64-bit value, then there are 64 bits to display.
在基本理论中,数字的实际宽度是存储大小的函数。如果是 32 位数字,则负数在一组 32 的 MSB 中具有 1。如果是 64 位值,则有 64 位要显示。
But in Python, integer precision is limited only to the constraints of your hardware. On my computer, this actually works, but it consumes 9GB of RAM just to store the value of x. Anything higher and I get a MemoryError. If I had more RAM, I could store larger numbers.
但在 Python 中,整数精度仅限于硬件的约束。在我的电脑上,这确实有效,但它消耗了 9GB 的 RAM 来存储x的值。任何更高的值,我都会收到 MemoryError。如果我有更多的 RAM,我可以存储更大的数字。
>>> x = 1 << (1 << 36)
So with that in mind, what binary number represents -1? Python is well-capable of interpreting literally millions (and even billions) of bits of precision, as the previous example shows. In 2's complement, the sign bit extends all the way to the left, but in Python there is no pre-defined number of bits; there are as many as you need.
那么考虑到这一点,什么二进制数代表-1?正如前面的示例所示,Python 能够很好地解释数百万(甚至数十亿)位的精度。在 2 的补码中,符号位一直向左扩展,但在 Python 中没有预定义的位数;有多少你需要的。
But then you run into ambiguity: does binary 1represent 1, or -1? Well, it could be either. Does 111represent 7or -1? Again, it could be either. So does 111111111represent 511, or -1... well, both, depending on your precision.
但是后来你遇到了歧义:二进制1代表1,还是-1?嗯,它可能是。是111代表7还是-1?再次,它可能是。所以确实111111111代表511,或者-1......好吧,两者都取决于你的精度。
Python needs a way to represent these numbers in binary so that there's no ambiguity of their meaning. The 0bprefix just says "this number is in binary". Just like 0xmeans "this number is in hex". So if I say 0b1111, how do I know if the user wants -1 or 15? There are two options:
Python 需要一种用二进制表示这些数字的方法,以便它们的含义没有歧义。该0b前缀只是说:“这个数字是用二进制”。就像0x意思是“这个数字是十六进制的”。所以如果我说0b1111,我怎么知道用户想要 -1 还是 15?有两种选择:
Option A:The sign bit
You could declare that all numbers are signed, and the left-most bit is the sign bit. That means 0b1is -1, while 0b01is 1. That also means that 0b111is also -1, while 0b0111is 7. In the end, this is probably more confusing than helpful particularly because most binary arithmetic is going to be unsigned anyway,and people are more likely to run into mistakes by accidentally marking a number as negative because they didn't include an explicit sign bit.
选项 A:符号位
您可以声明所有数字都是有符号的,最左边的位是符号位。这意味着0b1是 -1,while0b01是 1。这也意味着这0b111也是 -1,while0b0111是 7。最后,这可能比帮助更令人困惑,特别是因为大多数二进制算术无论如何都会是无符号的,而且人们更多可能会因不小心将数字标记为负数而出错,因为它们不包含明确的符号位。
Option B:The sign indication
With this option, binary numbers are represented unsigned, and negative numbers have a "-" prefix, just like they do in decimal. This is (a) more consistent with decimal, (b) more compatible with the way binary values are most likely going to be used. You lose the ability to specify a negative number using its two's complement representation, but remember that two's complement is a storage implementationdetail, not a proper indication of the underlying value itself. It shouldn't have to be something that the user has to understand.
选项 B:符号指示
使用此选项,二进制数表示为无符号数,负数有一个“-”前缀,就像它们在十进制中一样。这(a)与十进制更一致,(b)与最有可能使用二进制值的方式更兼容。您无法使用其二进制补码表示指定负数,但请记住,二进制补码是存储实现细节,而不是基础值本身的正确指示。它不应该是用户必须理解的东西。
In the end, Option B makes the most sense. There's less confusion and the user isn't required to understand the storage details.
最后,选项 B 最有意义。减少了混淆,并且不需要用户了解存储详细信息。
回答by PTEC Productions
For positive numbers, just use:
对于正数,只需使用:
bin(x)[2:].zfill(4)
For negative numbers, it's a little different:
对于负数,它有点不同:
bin((eval("0b"+str(int(bin(x)[3:].zfill(4).replace("0","2").replace("1","0").replace("2","1"))))+eval("0b1")))[2:].zfill(4)
As a whole script, this is how it should look:
作为一个完整的脚本,它应该是这样的:
def binary(number):
if number < 0:
return bin((eval("0b"+str(int(bin(number)[3:].zfill(4).replace("0","2").replace("1","0").replace("2","1"))))+eval("0b1")))[2:].zfill(4)
return bin(number)[2:].zfill(4)
x=input()
print binary(x)
回答by casevh
To properly interpret a binary sequence as two's complement, there needs to a length associated with the sequence. When you are working low-level types that correspond directly to CPU registers, there is an implicit length. Since Python integers can have an arbitrary length, there really isn't an internal two's complement format. Since there isn't a length associated with a number, there is no way to distinguish between positive and negative numbers. To remove the ambiguity, bin() includes a minus sign when formatting a negative number.
要将二进制序列正确解释为二进制补码,需要与序列相关联的长度。当您使用直接对应于 CPU 寄存器的低级类型时,存在隐式长度。由于 Python 整数可以具有任意长度,因此实际上没有内部二进制补码格式。由于没有与数字关联的长度,因此无法区分正数和负数。为了消除歧义,bin() 在格式化负数时包含一个减号。
Python's arbitrary length integer type actually uses a sign-magnitude internal format. The logical operations (bit shifting, and, or, etc.) are designed to mimic two's complement format. This is typical of multiple precision libraries.
Python 的任意长度整数类型实际上使用符号大小的内部格式。逻辑运算(位移、和、或等)旨在模拟二进制补码格式。这是典型的多精度库。
回答by AJP
tobin = lambda x, count=8: "".join(map(lambda y:str((x>>y)&1), range(count-1, -1, -1)))
e.g.
例如
tobin(5) # => '00000101'
tobin(5, 4) # => '0101'
tobin(-5, 4) # => '1011'
Or as clear functions:
或者作为明确的功能:
# Returns bit y of x (10 base). i.e.
# bit 2 of 5 is 1
# bit 1 of 5 is 0
# bit 0 of 5 is 1
def getBit(y, x):
return str((x>>y)&1)
# Returns the first `count` bits of base 10 integer `x`
def tobin(x, count=8):
shift = range(count-1, -1, -1)
bits = map(lambda y: getBit(y, x), shift)
return "".join(bits)
(Adapted from W.J. Van de Laan'scomment)
(改编自WJ Van de Laan 的评论)
回答by Enze Chi
def tobin(data, width):
data_str = bin(data & (2**width-1))[2:].zfill(width)
return data_str
回答by user3181121
Use slices to get rid of unwanted '0b'.
使用切片去除不需要的“0b”。
bin(5)[2:]'101'
bin(5)[2:]'101'
or if you want digits,
或者如果你想要数字,
tuple ( bin(5)[2:] )('1', '0', '1')
tuple ( bin(5)[2:] )('1', '0', '1')
or even
甚至
map( int, tuple( bin(5)[2:] ) )[1, 0, 1]
map( int, tuple( bin(5)[2:] ) )[1, 0, 1]
回答by pev.hall
A modification on tylerl's very helpful answer that provides sign extension for positive numbers as well as negative (no error checking).
对 tylerl 非常有用的答案的修改,为正数和负数提供符号扩展(无错误检查)。
def to2sCompStr(num, bitWidth):
num &= (2 << bitWidth-1)-1 # mask
formatStr = '{:0'+str(bitWidth)+'b}'
ret = formatStr.format(int(num))
return ret
Example:
例子:
In [11]: to2sCompStr(-24, 18)
Out[11]: '111111111111101000'
In [12]: to2sCompStr(24, 18)
Out[12]: '000000000000011000'
回答by user7857822
I hope this solves your problem`
我希望这能解决你的问题`
num = input("Enter number : ")
bin_num=bin(num)
binary = '0' + binary_num[2:]
print binary

