51: Bits Operations: Masking.
Take Up Code - A podcast by Take Up Code: build your own computer games, apps, and robotics with podcasts and live classes
Categories:
Working with individual bits doesn’t just give you a way to pack lots of true or false values into a small space. This episode will show you how to isolate bits so you can work with them individually or in groups. Isolating bits like this is called masking. The first thing to learn are the AND and OR truth tables. These tables list the output for each possible input combination. It is possible to consider AND and OR operations with more than two inputs but they need at least two inputs and that’s what these tables show. AND Truth Table 0 AND 0 => 0 0 AND 1 => 0 1 AND 0 => 0 1 AND 1 => 1 OR Truth Table 0 AND 0 => 0 0 AND 1 => 1 1 AND 0 => 1 1 AND 1 => 1 If you think of the first input in these tables as your mask value, then you can see how whenever the mask value is 0 for AND operations, then it doesn’t matter what the other input is. The output will always be 0. And whenever the mask value is 1 for AND operations, then the output matches the second input. For OR operations, the output matches the second value whenever the first mask value is 0. And whenever the mask value is 1, then the output will always be 1. In this episode, I explain how to clear the most significant bit in a byte by using a mask. We need to perform an AND operation to clear one or more bits. If we have the binary value: 1100 1010 and we want to convert this to: 0100 1010 by clearing the bit on the left, then we need this mask: 0111 1111 The mask value in hexadecimal is then 7f. And if we want to set the most significant bit again, then we need a different mask because this time, we will need to perform an OR operation. So continuing with this binary value: 0100 1010 and we want to convert to: 1100 1010 by setting the bit on the left, then we need this mask: 1000 0000 the mask value in hexadecimal is then 80. Listen to the full episode or you can read the full transcript below. Transcript The previous episode on hexadecimal showed you how you can divide an eight-bit byte in half and then use a single hexadecimal digit to represent each half. So instead of a binary value 10001000, you would break that into two values that are each 1000 which is 8. So the whole binary value 10001000 becomes 88 in hexadecimal. What if you wanted to isolate part of this value so you could work with just a portion. Maybe you only want the lower four bits. In other words, you want to turn 88 into 08 by clearing out all the upper four bits. This will let you work with just one hexadecimal digit. How would you do this? Before we get to the how though, let me explain why with another example. Normally, I try to find examples that are simpler than the original topic I’m trying to explain. This is an exception because I have a real example from some code that I wrote a while ago which I think captures a really good reason for why masking is needed. Let’s say that you need to transmit 4 byte integer values where the bytes have to be sent one by one. Now if you know that most of your values are small, then that means that the upper bytes will mostly be zeros. What if you could just not send those bytes if you don’t need to? If a large value comes along that’s using the bits in the upper bytes, then you go ahead and send them. But for the most part, you expect them to just occupy empty space. Maybe you could just send the bytes that are being used. You would need some way to mark how many bytes have been sent and on the receiving side, how many bytes were sent. One way to do this would be to use one bit from each byte as a signal. Let’s use the most significant bit in each byte. If this bit is zero, then that’s all. If this bit is one, then there’s at least one more byte following. Think of it like this. You have a group of people that can carry small messages for you. You can sometimes fit your entire message with one delivery person. When this happens, then before you send your delivery person, you j