1

I'm learning about bitwise operators in python and so I tried to do some experimentation in the shell. I tried doing bit manipulation with 8bit numbers and that seems to work normally, but if I try to use 16bit numbers this happens:

>>> b = 0010000000000000
>>> b
549755813888

If I try a larger number the output seems normal at first:

a = 1011110110011001
>>> a
1011110110011001

>>> b = 1100001110000101
>>> b
1100001110000101

But when I apply a bitwise operator, for instance OR |,then I get a decimal output again.

>>> a | b
1125874135965693

I find this very confusing. Isn't the result of binary operators supposed to be binaries? If so where does the conversion happen? And finally, why does this only happen when I try it with 16-bit binaries?

EDIT: I get the following when trying 8bits:

>>> c = 00000001
>>> d = 10000000
>>> c | d
10000001
Sifu
  • 153
  • 1
  • 17

3 Answers3

4

You haven't told Python that you're entering binary numbers; like C, Python will interpret 0010000000000000 as octal (8**13), and 1011110110011001 as decimal. Use the 0b prefix and bin function instead:

>>> a = 0b1011110110011001
>>> b = 0b1100001110000101
>>> bin(a|b)
'0b1111111110011101'

Your 8-bit (Python doesn't know that either, int is typically 32 or 64 bits but recent versions will seamlessly transition to long which can go to any width) values were interpreted the exact same way. It's just that 1 is 1 no matter how many zeroes are put in front, in any base, and the other number was even. Try 100 | 1000 (which produces 1004) for a low example where this fails (actual values are 0b1111101000 and 0b1100100).

Yann Vernier
  • 15,414
  • 2
  • 28
  • 26
  • This makes sense, but does the interpreter automatically recognize 8-bits as binaries without the '0b' prefix then? – Sifu May 04 '15 at 11:57
  • You might want to post an example of 8-bit values that you think are working. – chepner May 04 '15 at 12:00
1

Although you're only using 1s and 0s, this doesn't make the numbers you're typing in binary numbers: they're decimal (or octal if you start with 0).

If you want to use binary numbers, prefix them with 0b (assuming Python 2.6 at least). See this question.

You may also find bin() useful if you want to print out the results.


EDIT: I get the following when trying 8bits:

>>> c = 00000001
>>> d = 10000000
>>> c | d
10000001

You're still confused about the 0b notation. 10000000 isn't an 8-bit number, it's a decimal number, and you need at least 24 bits to represent it (bin(10000000) is 0b100110001001011010000000).

The reason 10000000 | 00000001 appears to "work" as if it was a binary representation is that 00000001 (which is an octal representation) also happens to be 1 in decimal. This really is 0b100110001001011010000000 | 0b000000000000000000000001.

For example, 00000010 is 8 in decimal, so 10000000 | 00000010 would be 10000008. If your number starts with 0, it's an octal representation; if it starts with 0x, it's hexadecimal; if it starts with 0b, it's binary; otherwise, it's decimal.

There is a bit of luck with your particular use case (10000000 | 1). Try 10000000 | 1000, and your assumptions no longer work: that's 10000360.

The operations you're using are bitwise, but the 1s in the numbers you are providing do not represent individual bits.

What you'd probably want to see is:

>>> bin(0b10000000 | 0b00001000)
'0b10001000'

Here the number you're providing are in binary format (0b...), the operation is bitwise (the operation was also bitwise for the other notations, it's just that the activated bits were not those you thought they were) and then you turn it back into a binary representation with bin(...).

Community
  • 1
  • 1
Bruno
  • 119,590
  • 31
  • 270
  • 376
0

To write binary literals in Python you need to prefix the literal with 0b. As in a = 0b1011110110011001. See this question for more detail.

Community
  • 1
  • 1
Benjy Kessler
  • 7,356
  • 6
  • 41
  • 69