Algorithms: Bit Manipulation

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
Hi, I'm Gayle Laakmann McDowell, author of Cracking the Coding Interview. Today we're going to talk about bits. So we're going to talk about how positive and negative numbers are represented in binary. We're going to talk about operations like shifting and arithmetic including the logical and the arithmetic shift. And then I'm going to talk about how we can use masks to do operations like clearing, setting, and getting bits. Now there's a little bit of cross dependency in these topics so the order might seem a little bit funny to be jumping back and forth but it'll be a little better this way. So let's relate this to base 10 numbers. What does a number like 583 mean? What do those digits represent? Well it's five times ten to the second, plus 8 times 10 to the first, plus 3 times 10 to the 0th. In base 2 or binary we can do the exact same thing. Now let's talk about adding. Well in base-10 we add up the two digits and if it hits our limit then we roll that over to the next digit so we added 3 and the 7, that gets ten, that hits our limit of ten, so we roll that one over and now we're adding a 1, an 8, and a 3, and that gives us 12 so we got a two down here that hits our limit of 10 so we roll that over up here, and then we're adding a 6, a 5 and a 1, and that again hits our limit of 10 per digit, so we go down that too and we carry the 1 over and we get 1220. So we can do that exact same thing in binary. In binary of course our limit of each digit is just 2, so we're going to add this 1 and this 1, and that's going to hit our limit of two so we're going to record a 0 over here, carry the one, now we're going to add again a 1, a 0, and a 1. That's going again hit our limit of 2 so I'm going to record a 0 there, carry the 1 over and now we're going to add a 1 and a 1. Again we're hitting this limit of two so we're going to record a 0 here and carry the 1 over and we get 1000. So that's again how you do binary addition. It's very very parallel to what you do in base-10. Now let's talk about how we represent negative numbers on a computer. Typically a negative integer is stored in two's complement form and what this means is that the very first bit is used to represent this sign. A 0 means it's it's a positive number and a one means it's negative. Then the remaining bits over here are filled in with the two's complement, the number that you'd have to add to these, to the positive version, to the absolute value to get 2 to the 8th in this case. We use 8 because it's an 8-bit number. So let's think about this. What number would we have to add to 00 100 10 to get 1 000 000 0. Well if we just added the inverse of 0 0 100 10 to it then we would get 0 with a whole bunch of ones afterwards. Therefore if we add 1 up here and a 1 down here we should get the values we're looking for. So remember that our original question was how do we represent negative 18 in binary? Well we take the positive value of that, the 18 and we look at this binary representation and then we say what number can we add to that to get one followed by whole bunch of zeros? Well the number we add to it to get all one's is just invert all the numbers so if we add 1 to a bunch of the, to both of those, then we have 110 1110 so therefore the two's complement, the number that you add to this series of bits here is in fact that number so our representation is this right here. So that's how you represent negative 18 in binary. So just to make sure you understand that. Let's look at one more example. So if we want to convert negative 123 to binary we'd be looking for the thing that we add to 123s non sign bits, so these bits over here, to get 2 to the 8th. So we'd take 123, convert it to binary, so we get that then invert all of the bits, and then we add 1 to that. And that will give us our two's complement version of negative 123. The next topic I want to talk about is shifting. Specifically two types of shifting, logical shifting and arithmetic shifting. So let's consider some number in binary like this. So if we want to left shift then we just move everything over by one to the left and if we want to right shift, move everything over by one to the righ. Now we've been talking about these in binary so much we forgot what these numbers actually are in base-10. Interestingly that top number is 23 and this left shift number is 46 and the right shift number is 11. Now what do you notice about those numbers? Well the left shift had the effect of multiplying that number by 2 and the right shift had the effect of dividing it by two. Of course with some truncation in there, and that's not a coincidence. That's what a left shift a right shift generally do. Now some of you might be wondering what happens on a negative number to this sign bit if we're doing a right shift? Does it shift with the number or not? And that's an interesting question. And that's where you get into logical vs arithmetic right shifts. So let's consider the number negative 23. In a logical right shift we do what we would logically think that a right shift would do, we move everything including the sign bit over. This gets us this weird value of 116 which doesn't really seem to have any particular relationship to the number negative 23. The arithmetic right shift operates slightly differently but in doing so preserves an arithmetic relationship between the original number and the new right shifted number. What the arithmetic right shift does is it shifts everything over by one including the sign bit but then it fills in the sign bit with the original sign bit instead of with a 0 as in the logical right shift. The resulting number is negative 12 which does still bear that sort of, that divide by 2 relationship, except that with negative 23 dividing by 2 is negative 11.5 so we're rounding to negative 12 this time. So now we're on to our final topic - using masks to do things like getting a bit, updating it, things like that. First let's review some of the basics. When we and two bits we get a 1 only if both of those bits are 1. When we or two bits we get a 1 if either of those two bits are 1. And when we do an XOR we need exactly one of those two bits to be a 1. If both are ones we get a zero. So now let's turn to how you would get a particular bit and a number. So how do we figure out if say this bit was a one or a zero? Well if we create a mask or just a number that has a 1 only in that one bit and we and it with the original number that will indicate whether that value is a one or a zero because if there's a zero there the whole number will be 0. Otherwise it'll be something bigger than 0, so that mass can be created by taking one and shifting it over to the left by i spots. So to figure out if the ith spot is a one or a zero we just compare X, do an and of X with that mask and say does that not equal 0? Now what about setting the ith bit? Well we can do a very similar thing. We create actually exact, the exact same mask and we just or it with that original value. And that will make sure that ith bit is set. Now what about clearing the ith bit? Well that's a little bit trickier but still very doable. What we want to do is end it with a mask that has a 1 everywhere else but that one spot. But how do we create such a mask? Well all we have to do actually is just take the mask from before and invert it and that's exactly what you see here. So we've now covered the basics of bit manipulation. We talked about how numbers are represented both in positive and negative form, and then we talked about different operations like, how we add numbers comparing that to base 10 numbers. We talked about shifting both logical and arithmetic and then we talked about how to do getting, setting, and clearing using masks. So from candidates there's a lot of focus on learning different bit manipulation tricks and things like that. What I really encourage people to do is just really solidify their understanding of the basics and from there a lot of these tricks and things like that will follow, but really nail that foundation of the basics. So now that you've seen these basic operations why don't you try your hand at a new bit manipulation problem. Good luck.
Info
Channel: HackerRank
Views: 420,872
Rating: undefined out of 5
Keywords:
Id: NLKQEOgBAnw
Channel Id: undefined
Length: 9min 5sec (545 seconds)
Published: Tue Sep 27 2016
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.