bsl
bsl

Reputation: 19

Python bitwise operations confusion

I came up with this "magic string" to meet the ID3 tagging specification:

The ID3v2 tag size is encoded with four bytes where the most significant bit (bit 7) is set to zero in every byte, making a total of 28 bits. The zeroed bits are ignored, so a 257 bytes long tag is represented as $00 00 02 01.

>>> hex_val = 0xFFFFFFFF
>>> str.format('0b{0:07b}{1:07b}{2:07b}{3:07b}', ((hex_val >> 24) & 0xEF),
                                                 ((hex_val >> 16) & 0xEF), 
                                                 ((hex_val >>  8) & 0xEF),
                                                 ((hex_val >>  0) & 0xEF))
'0b11101111111011111110111111101111'

Why does it not equal:

'0b11111111111111111111111111111111'

?

If anyone cares, this seems to work:

>>> int(str.format('0b{0:07b}{1:07b}{2:07b}{3:07b}', ((hex_val >> 24) & 0xFE),
                                                     ((hex_val >> 16) & 0xFE),
                                                     ((hex_val >>  8) & 0xFE), 
                                                     ((hex_val >>  0) & 0xFE)), 2)

Upvotes: 0

Views: 1359

Answers (3)

Jonathan Feinberg
Jonathan Feinberg

Reputation: 45324

It does not equal all ones because you're masking out the 4th bit using the & operator!

Upvotes: 1

bsl
bsl

Reputation: 19

Sorry getting my 7s and Es confused

Corrected code:

>>> str.format('0b{0:07b}{1:07b}{2:07b}{3:07b}', ((hex_val >> 24) & 0x7F),
                                                 ((hex_val >> 16) & 0x7F),
                                                 ((hex_val >>  8) & 0x7F),
                                                 ((hex_val >>  0) & 0x7F))

Upvotes: 1

u0b34a0f6ae
u0b34a0f6ae

Reputation: 49803

I think you are confusing the and and the or operations.

  • bitwise and: return a number with only bits that are in both operands set.
  • bitwise or: return a number with bits that are in either of the operands set.

Upvotes: 2

Related Questions