Lesson 4 of 9
Bitwise operations
- 13 min
- 5 checks
- 3 hints
- Go to task
Goal
Masks and shifts take a byte apart
Explanation
A single byte often carries several pieces of information, like flags in individual bits, or two small numbers in its two halves. To take it apart you need bitwise operations:
a & b(AND) gives a 1 bit only where both numbers have a 1.a | b(OR) gives a 1 bit where either number has a 1.a ^ b(XOR) gives a 1 bit where the two bits differ.- The shift
a << nmoves the bits n places to the left, which multiplies the number by 2 to the power of n. - The shift
a >> nmoves them to the right, which divides the number and drops the fraction. ~aflips every bit.
A bitmask is a number you use to pick out the bits you want. The mask 0x0f, which is 0000 1111, isolates the low half of a byte, and the shift >> 4 brings the high half down into its place:
1010 0110 flags = 0xA6 & 0000 1111 mask = 0x0f = 0000 0110 low = 6 1010 0110 >> 4 = 0000 1010 high = 10
To find out whether bit n is set, isolate it with its mask and compare the result with zero. Bits are numbered from the right, starting at zero. To flip a single bit, XOR it with its mask. And note that ~ in Python gives a negative number, so mask the result with 0xff to stay within a byte:
(flags & (1 << n)) != 0 # is bit n set? flags ^ (1 << n) # flips bit n ~flags & 0xff # flips every bit
Your task
Write a function parse_flags(b) that returns a tuple of four values from the byte b, in this order: its high half, its low half, whether bit 5 is set (True or False), and the byte after flipping bit 0. Then use it to unpack flags into the variables high, low, is_set and toggled.
Checks
5 checks- high is the high half
- low is the low half
- is_set is the right boolean
- toggled has bit 0 flipped
- parse_flags works on other bytes