Why can't a multi-swap bit-reversion work for minus number in Python 3?

0

In Python 3, I want to do bit-reversion with treating integers as 32-bit. I hope to achieve so in a swap style, as we usually see in C, namely

def rev(n):  # 32-bit bit-reversion
    n = (n >> 16) | (n << 16)
    n = ((n & 0xff00ff00) >> 8) | ((n & 0x00ff00ff) << 8)
    n = ((n & 0xf0f0f0f0) >> 4) | ((n & 0x0f0f0f0f) << 4)
    n = ((n & 0xcccccccc) >> 2) | ((n & 0x33333333) << 2)
    n = ((n & 0xaaaaaaaa) >> 1) | ((n & 0x55555555) << 1)
    return n

However, the results are unexpected. For positive inputs, the results are lack of zeros. For minus inputs, the results are all-ones.

print(bin(240))                   #                          0b11110000
print(format(240, '#034b'))       #  0b00000000000000000000000011110000
print(bin(rev(240)))              #  !!! 0b1111000000000000000000000000   
print(format(rev(240), '#034b'))  #  0b00001111000000000000000000000000

print(bin(-240))                  #                         -0b11110000
print(format(-240, '#035b'))      # -0b00000000000000000000000011110000
print(bin(rev(-240)))             #  0b11111111111111111111111111111111 !!!
print(format(rev(-240), '#034b')) #  0b11111111111111111111111111111111

I found some solution to reserve bit order by string manipulation. Such as

int('{:08b}'.format(n)[::-1], 2)

(( Ref = Reversing bits of Python integer ))

But I would like to achieve so in purely bitwise fashion and learn how Python 3 store integers and do bit-operation.

I also found that, by using a mask, the results will be what I expected

print(bin(240&0xFFFFFFFF))                    #                          0b11110000
print(format(240&0xFFFFFFFF, '#034b'))        #  0b00000000000000000000000011110000
print(bin(rev(240&0xFFFFFFFF)))               #  0b1111000000000000000000000000
print(format(rev(240&0xFFFFFFFF), '#034b'))   #  0b00001111000000000000000000000000

print(bin(-240&0xFFFFFFFF))                   #  0b11111111111111111111111100010000
print(format(-240&0xFFFFFFFF, '#034b'))       #  0b11111111111111111111111100010000
print(bin(rev(-240&0xFFFFFFFF)))              #  0b1000111111111111111111111111
print(format(rev(-240&0xFFFFFFFF), '#034b'))  #  0b00001000111111111111111111111111

I guess my question is related to how Python 3 stores integers and signs. Thank you for you kind help.

python
python-3.x
integer
ones-complement
bit-representation
asked on Stack Overflow Jul 12, 2019 by y56 • edited Jul 13, 2019 by y56

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0