Python Bitwise Shifts
00:00 In the previous lesson, I covered the bitwise operators AND, OR, and NOT. In this lesson, I’ll show you how to use bitwise shifting. The left and right shift operators move the bits a number of positions to the left or right, respectably. New bits shifted in are of 0 value.
00:21 Because each bit in a binary number is a power of 2, a bit shift is equivalent to a multiplication or division by 2. This is no different than multiplying by 10 in decimal. Shift the digits left and add a 0.
00:36 Shifting is usually more performant than multiplication, and so this is an old-school trick for times 2. This trick was very common in the gaming industry with low-level languages.
00:48 It is an old-school trick, though, and not really worth it anymore. Optimized compilers know this trick and will do it for you with the added benefit of not confusing the programmer who is maintaining your code.
01:01 Let’s start by shifting some decimal values. 4 shifted left by 1 is multiplying by 2, giving 8. 4 shifted left by 4 is multiplying by 2 four times. That’s 16, giving a result of 64.
01:21 No different for non powers of 4. Now, 312 is bigger than a single byte. What if you only want to deal with a single byte? Python doesn’t have a byte data type, but you can emulate it with a bitmask.
01:38 A bitmask is a series of bits that you’d typically AND with a number. Oftentimes, these masks are a series of 1s. In this case, 255 is eight 1s in binary.
01:50 Applying the mask to the bit shift removes any bits above the eighth position, mimicking an eight-bit byte. The bits above the eighth position are gone, and what is left from 312 is the lower eight bits, giving 56 in decimal.
02:10 Shifting right is division by 2.
02:14 And for numbers that don’t evenly divide, it works like a floor division.
02:21
Python’s double-slash division operator (//
) is a floor division, which contrasts to the regular division operator (/
), which in this case results in a float. How about some negatives?
02:35 Shifting isn’t as problematic as NOT-ing. Two’s complement is happy to multiply by 2.
02:45 No different for right shifts, either.
02:49 You may recall that I said that the bits shifted in are zeros. That’s a bit of a—ahem, lie, ahem—over simplification. Python actually does what is called an arithmetic shift.
03:02 That is a shift that preserves the sign bit. Think back to those negative numbers I just shifted for you. It felt all reasonable that -16 shifted right by 1 is -8 because of the whole division by 2 thing. But if a 0 had been shifted in on the left side, like with positive numbers, you wouldn’t get -8.
03:22 You’d get a positive number because you’re pushing the sign bit out of the sign position. This is called an arithmetic shift. By contrast, the other kind of shift is called a logical shift.
03:35
A logical shift ignores the sign bit and pushes a 0 in, changing negative numbers. Some programming languages support a logical shift operator. In Java and JavaScript, it’s three greater thans (>>>
).
03:50 Other languages automatically choose between arithmetic and logical operators based on the data type the operation is being invoked upon. Python doesn’t support anything but arithmetic, but you could mimic the logical shift with the judicious use of a bitmask.
04:08 Okay, so you’ve now seen the common bitwise operations in Python. What good are they? In the next lesson, I’ll run you through some common use cases for bitwise operators.
Become a Member to join the conversation.