两个';Python中的二进制补码?

两个';Python中的二进制补码?,python,binary,bit-manipulation,Python,Binary,Bit Manipulation,Python中的整数存储在2的补码中,对吗 尽管: >>> x = 5 >>> bin(x) 0b101 以及: 那太差劲了。我如何让python以实二进制位给出数字,并且前面没有0b?因此: >>> x = 5 >>> bin(x) 0101 >>> y = -5 >>> bin(y) 1011 我不完全确定您最终想要做什么,但您可能想看看软件包。如果您提供一个面具,效果最好。通过这

Python中的整数存储在2的补码中,对吗

尽管:

>>> x = 5
>>> bin(x)
0b101
以及:

那太差劲了。我如何让python以实二进制位给出数字,并且前面没有0b?因此:

>>> x = 5
>>> bin(x)
0101
>>> y = -5
>>> bin(y)
1011

我不完全确定您最终想要做什么,但您可能想看看软件包。

如果您提供一个面具,效果最好。通过这种方式,您可以指定符号延伸的距离

>>> bin(-27 & 0b1111111111111111)
'0b1111111111100101'
或者更一般地说:

def bindigits(n, bits):
    s = bin(n & int("1"*bits, 2))[2:]
    return ("{0:0>%s}" % (bits)).format(s)

>>> print bindigits(-31337, 24)
111111111000010110010111
在基本理论中,数字的实际宽度是存储器大小的函数。如果是32位数字,则负数在32集的MSB中具有1。如果是64位的值,则有64位可显示

但在Python中,整数精度仅限于硬件的约束。在我的计算机上,这实际上是可行的,但仅仅为了存储x的值就消耗了9GB的RAM。再高一点,我就会得到一个记忆体。如果我有更多的内存,我可以存储更多的数字

>>> x = 1 << (1 << 36)

>>x=1对于正数,只需使用:

bin(x)[2:].zfill(4)
对于负数,有点不同:

bin((eval("0b"+str(int(bin(x)[3:].zfill(4).replace("0","2").replace("1","0").replace("2","1"))))+eval("0b1")))[2:].zfill(4)
作为一个整体脚本,它应该是这样的:

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)
def二进制(数字):
如果数字<0:
返回仓位((eval(“0b”)+str(int(仓位(编号)[3:].zfill(4)。替换(“0”,“2”)。替换(“1”,“0”)。替换(“2”,“1”)))+eval(“0b1”)))[2:]zfill(4)
退货箱(编号)[2:]zfill(4)
x=输入()
打印二进制文件(x)

不确定如何使用标准库获取所需内容。有一些脚本和包可以为您进行转换

我只是想指出“为什么”,为什么它不是跛脚的

bin()不返回二进制位。它将数字转换为二进制字符串。根据python语言定义,前导的“0b”告诉解释器您正在处理一个二进制数。通过这种方式,您可以直接处理二进制数,如下所示

>>> 0b01
1
>>> 0b10
2
>>> 0b11
3
>>> 0b01 + 0b10
3
那可不差劲。太好了


垃圾箱(x)

将整数转换为二进制字符串

整数和长整数文字由以下词汇定义描述:

bininteger::=“0”(“b”|“b”)bindigit+

bindigit::=“0”|“1”


为了正确地将二进制序列解释为二的补码,需要有一个与序列相关的长度。当您处理与CPU寄存器直接对应的低级类型时,存在一个隐式长度。由于Python整数可以具有任意长度,因此实际上不存在内部2的补码格式。由于没有与数字相关联的长度,因此无法区分正数和负数。为了消除歧义,在格式化负数时,bin()包含一个减号

Python的任意长度整数类型实际上使用了符号大小的内部格式。逻辑运算(位移位、and、or等)被设计成模拟2的补码格式。这是典型的多精度库

tobin = lambda x, count=8: "".join(map(lambda y:str((x>>y)&1), range(count-1, -1, -1)))
e、 g

或作为明确的功能:

# 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)

(根据评论改编)

使用切片来去除不需要的“0b”

bin(5)[2:][/code>
‘101’

或者如果你想要数字

tuple(bin(5)[2:])
('1','0','1')

甚至

map(int,tuple(bin(5)[2:])
[1,0,1]


对tylerl非常有用的答案的修改,为正数和负数提供符号扩展(无错误检查)


我希望这能解决您的问题`

num = input("Enter number : ")
bin_num=bin(num)
binary = '0' + binary_num[2:]
print binary

这里有一个更具可读性的版本,例如,假设您希望在其8位的-2负表示“两个补码”:

2**8代表第九位(256),减去1,前面的所有位都设置为一(255)

对于8位和16位掩码,可以用0xff或0xffff替换(2**8-1)。十六进制版本在这一点之后变得不那么可读

如果这一点不清楚,以下是它的常规功能:

def twosComplement (value, bitLength) :
    return bin(value & (2**bitLength - 1))

不用了,已经是了。这只是python选择以不同的方式表示它。如果你开始单独打印每个小字,它会显示出它的真实颜色

checkNIB = '{0:04b}'.format
checkBYT = lambda x: '-'.join( map( checkNIB, [ (x>>4)&0xf, x&0xf] ) ) 
checkBTS = lambda x: '-'.join( [ checkBYT( ( x>>(shift*8) )&0xff ) for shift in reversed( range(4) ) if ( x>>(shift*8) )&0xff ] )


print( checkBTS(-0x0002) )
输出很简单:

>>>1111-1111-1111-1111-1111-1111-1111-1110  

现在,当您想显示一个半字节的两个补码时,它将恢复为原始表示,但如果您将它分成半个半字节,那么仍然有可能请记住,最好的结果是使用负十六进制和二进制整数解释简单的数字,而使用十六进制可以设置字节大小

一个负数的意思是模值减去正值。 所以我认为,赞美-27的简单方式是

bin((1<<32) - 27)  // 32 bit length  '0b11111111111111111111111111100101'
bin((1<<16) - 27)
bin((1<<8) - 27)   // 8 bit length  '0b11100101'

bin((1我们可以利用按位异或的属性。使用按位异或翻转位,然后添加1。然后可以使用python内置的bin()函数获取2的补码的二进制表示形式。下面是一个示例函数:

def twos_complement(input_number):
    print(bin(input_number))                            # prints binary value of input
    mask = 2**(1 + len(bin(input_number)[2:])) - 1      # Calculate mask to do bitwise XOR operation
    twos_comp = (input_number ^ mask) + 1               # calculate 2's complement, for negative of input_number (-1 * input_number)
    print(bin(twos_comp))                               # print 2's complement representation of negative of input_number.   

它的存储方式是一个实现细节。它的可能重复不会产生负数的请求结果。结果应该是
1011
,而不是
101
。现在,它对其他数字给出了错误的结果。
binary(-4)
应该是类似于
1100
111111 00
,但这给出了
11
,这是完全错误的。哦,我的错误,程序现在使用2的恭维+1,为了生成打印表示,这是最简单的方法。(不过请记住,
-27&0b111111111
的实际结果在内存中是一个正数!)@senderle如果最高有效位为0,它只是一个正数。有多少位?这是你用掩码决定的。如果你决定你不受限制
bin(-2 & (2**8-1))
def twosComplement (value, bitLength) :
    return bin(value & (2**bitLength - 1))
checkNIB = '{0:04b}'.format
checkBYT = lambda x: '-'.join( map( checkNIB, [ (x>>4)&0xf, x&0xf] ) ) 
checkBTS = lambda x: '-'.join( [ checkBYT( ( x>>(shift*8) )&0xff ) for shift in reversed( range(4) ) if ( x>>(shift*8) )&0xff ] )


print( checkBTS(-0x0002) )
>>>1111-1111-1111-1111-1111-1111-1111-1110  
bin((1<<32) - 27)  // 32 bit length  '0b11111111111111111111111111100101'
bin((1<<16) - 27)
bin((1<<8) - 27)   // 8 bit length  '0b11100101'
def twos_complement(input_number):
    print(bin(input_number))                            # prints binary value of input
    mask = 2**(1 + len(bin(input_number)[2:])) - 1      # Calculate mask to do bitwise XOR operation
    twos_comp = (input_number ^ mask) + 1               # calculate 2's complement, for negative of input_number (-1 * input_number)
    print(bin(twos_comp))                               # print 2's complement representation of negative of input_number.