python中左移运算符的混淆

时间:2014-01-28 12:10:49

标签: python bit-manipulation

我试图在整数

的16位二进制表示上使用左移运算符

编写的代码如下:

def showbits(x):
    return bin(x)[2:].zfill(16)
i=5225
print "Decimal %d is same as binary" % (i)
print showbits(i)
for j in range(0,5,1):
    k=i<<j
    print "%d right shift % gives" % (i,j)
    print showbits(k)

输出:

Decimal 5225 is same as binary
0001010001101001
5225 right shift  0ives
0001010001101001
5225 right shift  1ives
0010100011010010
5225 right shift  2ives
0101000110100100
5225 right shift  3ives
1010001101001000
5225 right shift  4ives
10100011010010000

主要的问题是,当它移动前导'1'时,它并没有消失,而是再增加一点...

任何解决方案?

2 个答案:

答案 0 :(得分:7)

掩盖结果值,&按位AND:

mask = 2 ** 16 - 1
k = (i << j) & mask

此处16是您想要的位宽;您可以使用i.bit_length()将其限制为i所需的最小大小,但这意味着任何左移会丢弃位。

掩码形成一系列1位,其宽度与原始值相同; &操作将任何位设置为 之外的

>>> 0b1010 & 0b111
2
>>> format(0b1010 & 0b111, '04b')
'0010'

一些旁注:

  • 转移,而不是右移。
  • 您似乎忘记了调试版中的d

    print "%d left shift %d gives" % (i,j)
    

    其中%只有ggives %g相结合才能生成def showbits(x): return format(x, '016b') (浮点格式化)。

  • 您可以使用:

    0b

    将整数格式化为0填充的16个字符宽的二进制表示,不带 {{1}}前缀。

答案 1 :(得分:0)

因为Python可以防止出现这种情况(称为溢出)。它通过调整类型来实现:

>>> i = 5225
>>> type(i)
<type 'int'>
>>> j = i << 16; type(j); bin(j)
<type 'int'>
'0b10100011010010000000000000000'
>>> j = i << 32; type(j); bin(j)
<type 'int'>
'0b101000110100100000000000000000000000000000000'
>>> j = i << 64; type(j); bin(j)
<type 'long'>
'0b10100011010010000000000000000000000000000000000000000000000000000000000000000'
>>> j = i << 128; type(j); bin(j)
<type 'long'>
'0b101000110100100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'

如果你想限制你想要使用的位,可以像Martijn建议的那样使用16位掩码。

>>> j = 0xffff & (i << 12); type(j); bin(j)[2:].zfill(16)
<type 'int'>
'1001000000000000'
>>> j = 0xffff & (i << 13); type(j); bin(j)[2:].zfill(16)
<type 'int'>
'0010000000000000'
>>> j = 0xffff & (i << 14); type(j); bin(j)[2:].zfill(16)
<type 'int'>
'0100000000000000'
>>> j = 0xffff & (i << 15); type(j); bin(j)[2:].zfill(16)
<type 'int'>
'1000000000000000'
>>> j = 0xffff & (i << 16); type(j); bin(j)[2:].zfill(16)
<type 'int'>
'0000000000000000'