Python Bitwise AND, OR, and NOT
00:12 This course has a lot of theory in it, and in case you skipped straight to the Python stuff, here is a quick recap. Binary storage is founded on base-2 math, with each bit in a binary value representing a power of 2. Negative numbers can be stored in several different ways, the most common of which is called two’s complement representation.
00:34 Python has two internal mechanisms for storing integers, which it switches back and forth between: Fixed precision, which is typically an eight-byte number, and arbitrary precision, which is a big num object representation without an upper limit.
0o prefix specifies octal.
52 in octal is
42 in decimal. Note that some other programming languages use a different prefix for octal, just a leading zero. Python explicitly disallows this to avoid confusion.
They’re just different ways of inputting the same
42 stored the same way internally every time. Let’s put this in a variable. No surprises so far. Now, what if you want to see the binary representation of this value?
There are several ways of accomplishing this. If you’re okay with a string representation, you can use the formatting feature of the f-string. Here, the
:b says to output the number in binary format.
Here, I’ve combined two binary values. Recall that AND (
&) looks for bits that are in both numbers. In this case, that’s the third bit. The third position is 2 to the power of 2, remember the first bit is 2 to the 0, and of course, 2 squared is 4.
A 1 bit in either value causes a 1 bit in the result—in this case, four 1 bits. Well that’s AND and OR. How about NOT (
~)? Well, that’s a bit unexpected. What happened here? For starters, understand that just because you input four bits doesn’t mean the math is being done on a four-bit number. Python integers on most platforms are eight bytes long.
That gives you sixty-one 1 bits, two 0s, and then a final 1 bit. This is the two’s complement representation of -7 decimal. The
bin() function then tries to be helpful. Rather than show the two’s complement number, it pulls the sign out front and then shows the positive value.
Let’s do that again without the call to
bin(). Like I said,
-7. Doing it another way. It might be weird, but it is consistent. You might recall from the lesson on two’s complement that NOT 0 is -1.
bin() gives the signed-magnitude output once again. Okay. So, this is a bit ugly. Is there anything else that can be done? Well, sort of. Let me import the
c_uint8 (C unsigned int8) object from the
This module is typically used to interact with C language extensions.
c_uint8 is short for C-language unsigned integer eight bits. I’ve renamed that to the slightly more friendly
unsigned_byte during the import.
Creating an unsigned byte with a value of
214 decimal. As the byte is unsigned, the two’s complement representation of -42 has flipped the same bits that result in
214 in unsigned mode.
You can use the value accessor of the unsigned byte object to get the contents back out as a regular old integer. Great! So this solves our problem. Why did I spend all that time talking about the fact that Python doesn’t have an unsigned integer? Why not just use the
It turns out
ctypes doesn’t support bitwise operations. They’re helpful for conversions, but can’t be used as a replacement for an unsigned int. What’s that old thing about skinning cats? Let’s look at the
array object from the
08:31 But also like the array, if you start manipulating these values, you’re back in integer land and all the problems that that entails. There is a solution, but it doesn’t come standard with the Python library.
09:30 And remember good old -7? A solution! This isn’t a negative number, and it also isn’t the weird signed-magnitude binary string. This is an actual inverted unsigned int. The REPL shows the integer value, but underneath, this is still a NumPy object.
10:08 And the ugly -7 problem has gone away. Depending on your use case, NumPy is probably overkill. If you’re just keeping some binary flags and sticking with positive numbers, you don’t need this. But if you’re doing hardcore bit manipulation, having access to a true unsigned value could be useful.
Become a Member to join the conversation.