Learning Diary: Bitwise Operations
Okay, I am confident that either I should have learned this in college, that I did and forgot it in the ensuing decade. My binary was already on the rusty side, and I felt like I was having some trouble keeping up with the lessons. Code Academy had some great step by step stuff, but I felt like I was missing the fundamentals.
I went ahead and finished the lesson after watching the video above, which I felt broke down exactly what was happening with the data. I’m going to post my half-assed summary here to try and help cement it in my brain.
Writing Binary Numbers In Python
Since I didn’t learn Python in college, Java was still all the rage with some pit stops in C++ and SQL. This was something I had to learn from scratch.
Like most things in Python, it’s fairly easy to pick up and remember. You simply write out your binary number in 1’s and 0’s with 0b in front of it. Here’s a couple of quick examples:
25 = 0b11001
16 = 0b10000
10 = 0b1010
2 = 0b10
I am not too sure how often you’d run into this as a hobby coder. In my day job, I’ve mostly coded out automation. On the data side, it’s been chiefly AD queries, so there isn’t much need for optimizing numerical values. It’s still a good trick to have up your sleeve if you ever do need it.
Getting Out The Pen and Paper
I think that the best step I did for myself was grabbing a pen and notebook to work on this. Being able to crib what place in the count I was on made it easier to add up numbers in my head. Once you get into the exercises, it will also be easier to think through exactly what happens at each step of the process.
Left Shift and Right Shift
The operators >> and << each stand for right shift and left shift respectively. If that doesn’t quite make sense, don’t worry. This was the point where I went looking around for a couple of tutorials.
This is because binary is a bit different from decimals and integers. Since you’ve got the number 10 held as 1010, you then would apply shift right one to make that 0101 or shift left one to make that 10100. That changes the value to 5 or 20.
In Python you would set a variable to a binary value and then apply the >> with the number of places you’re shifting. So in the case above it would be:
shift_right = 0b1010 >> 2
shift_left = 0b1010 << 2
So the question is, what would we use these for? It may not be something that a hobby coder is going to spend much time with. On the other hand, if you’re looking to squeeze every bit of performance from the code you’ve written, these shifts come in handy. If you’re mathematically inclined, you may have noticed that shifting left is the equivalent of multiplying the number by 22 and shifting right is close to dividing by 22. Because we're working with integers, it rounds down.
And Operations
Things get a little easier here but keep your notebook out. You use AND to evaluate two integers in binary. The result is all of the bits where both numbers are 1. So we'll convert the two numbers 25 and 30 into binary and use AND to compare them to get 24.
11001
11110
11000
I'm pretty much out of my depth here for real-world applied uses. However, if you do come across a reason to know what registers are active for two numbers in Python you can use the & symbol to get the result.
twenty_five = 0b11001
thirty = 0b11110
and_value = twenty_five & thity
Or Operations
This is another fairly straight forward to understand, especially if you write this out on paper. Like the previous section, we use OR to compare two integers. Instead of only flipping bits where both integers are 1, we will flip it if either integer is 1. We'll use 25 and 30 again, but this time we end up with 31 as our final result.
11001
11110
11111
Again, this is mostly used for quick checks and bit masking on resource constrained systems. In Python, we'll make this comparison with the | character.
twenty_five = 0b11001
thirty = 0b11110
or_value = twenty_five | thirty
XOr Operations
Short for Exclusive Or, XOR is another example where we compare two integers. This time, however, you're only returning 1 if the bit set in just one of the two integers. Looking again at 25 and 30 we end up with 7 as the result.
11001
11110
00111
XOR functions are fundamental to the way that CPUs do math, as well as some early graphics and cryptography programs. In Python, you get these by using the ^ operator.
twenty_five = 0b11001
thirty = 0b11110
xor_value = twenty_five ^ thirty
Not Operations
Not operations are a bit simpler, simply because you call them on a single integer. What they do is flip every bit in the number to its opposite. All the 0's become 1's and vice verse. We'll take a look at 25 and 30 in two separate boxes to look at their transformations. 25 becomes 7, and 30 becomes 1.
11001
00110
11110
00001
When working with these in Python is done with the ~ character.
twenty_five = 0b11001
thirty = 0b11110
xor_twenty_five = ~twenty_five
xor_thirty = ~thirty
Thinking At A Machine Level
If you're a developer in any capacity, you're likely scratching your head as to why I thought this was interesting enough for a couple of hundred words. I felt like this was worth going over as it was a concept that I hadn't retained at all from college. These posts are just as much about reinforcing concepts to myself, as sharing cool things I have figured out using code.
I found something that I was stuck on, and more than anything wanted to explore the concept in a way that would cement it in my head. Also, I know that these work for more than just integers, but for simplicity's sake I limited the math to those as it is the most straightforward. If you're an experienced programmer, and you're using these, I'd love for you to share those practical examples in the comments.
I'm coming up on the end of the second Code Academy Python course, and have a book called Automate The Boring Stuff with Python. I've been trying to get back into the swing of coding outside of work, so these posts should pop up a little more often.
Rants and Reviews. Mostly just BS and Affiliate Links.
Follow on Mastodon