Working With Individual Bits and Bytes Let's Your Code Go Beyond Fast And Helps You Keep Track Of Combinations That Would Be Overwhelming
When I was studying electronics in college, the school didn’t need to justify any of the classes. At least not to the students. I was told which classes to take and expected to follow that schedule if I wanted to graduate.
I learned a lot of useless things in college. Have I ever needed to write a five paragraph essay? Not since some professor at school said that I needed to learn how to write within the strict rules he provided.
I’ve since learned to do things that work. And if that means my sentences are not fully formed, that’s okay. I’ve also learned to teach things that are important. This class is important. I wouldn’t have put it in the essential classes if it could wait.
Learning about bits and bytes might seem like some low-level details, or maybe even a dry and boring math lesson. It’s actually one of the really useful skills I learned from electronics. The title of this class doesn’t fully describe how useful it is. I struggled with that. Maybe I’ll think of a better name later.
The C++ language is flexible. It lets you work on high-level design when you need to and go all the way to individual bits when you need to. I mentioned in the title that learning this will help you squeeze extra speed from your code. It’s more than just speed though.
What would you do if you have three options that you can turn on or off and you need to keep track of them all in your code? Maybe you’re writing code for a sandwich shop and you need to keep track of whether the sandwich should be toasted or not, if it should be full length or half, and if it should have tomatoes or not. You could use three separate bool variables for this.
If you did that, then you’d have to pass those three variables everywhere in your code that needed to know the sandwich options.
What if you listed each option combination and gave each possible combination a number? This is just like counting in binary. With three options, you’ll have eight combinations. Now you only need to pass around the number representing that combination. In exchange for only needing to pass a single number, you have eight combinations to remember which number means what. That doesn’t seem like a very good tradeoff.
Especially when you want to add more options. What if you now need to track whether or not to add onions, lettuce, pickles, olives, and cheese? This brings the total number of options to eight. And that brings the total number of combinations to 256.
You’re going to need a different solution because keeping track of eight separate bool variables even if you put them all in a struct is getting tedious. And keeping track of every possible combination became completely unworkable at about four options.
A single byte has eight bits in it. And these bits can be zero or one. Or off and on if you want to think of them like that. You just need a way to get to individual bits quickly and easily.
That’s the real power of this class. It’s hard to put that in a title. There’s three parts to this class.
In the first part, you’ll learn about number systems. I mentioned that three options is just like counting to eight combinations. Why? How does that work exactly?
- Binary – base 2
- Decimal – base 10
- Hexadecimal – base 16
Data can come in different sizes allowing you to use bigger values.
- Single binary digit. Not directly addressable in computers.
- Consists of 4 bits.
- Some really old microprocessors used nibbles.
- They’re still useful today as a single hexadecimal digit.
- Usually consists of 8 bits or 2 nibbles. The term octet is sometimes used to be more specific that this really is an 8 bit value.
- The smallest size of data that’s usually directly addressable in a computer. This means that every byte has its own memory address.
- Started as the term used to describe the native data size for a processor. Now it’s mostly used to represent 16 bit or 2 byte values.
- Double words
- The term used for 32 bit or 4 byte values. This is sometimes called a DWORD.
- Quad words
- The term used for 64 bit or 8 byte values.
Learn about the least and most significant digits so you can identify individual bits to work with.
Learn what it means to shift bits left or right. You’ll need this if you want to get your bits into the proper place. And it’s also a great way to quickly multiply or divide.
The second part starts here and you’ll learn how to represent small and large positive values.
- Using fixed width encoding.
- Or using variable width encoding.
How to represent negative values.
- With two’s complement.
- Or with a really cool zigzag encoding that works especially well with variable width encoding for small values.
Learn how to add and subtract in each base system.
Overflow and how it can cause your values to wrap around to zero. This can be an interesting source of security vulnerabilities in your code if you’re not careful.
The third part starts here and you’ll learn how to represent fractional values.
- Fixed precision that reserves bits for fractional values.
- IEEE floating point values that are used everywhere.
- Separate numerator and denominator values will let you keep track of exact fractions with no rounding error.
- Decimal types let you avoid rounding errors that we don’t have with our normal decimal system.
Characters and text are also represented with bits and bytes.
- With fixed width encoding
- With variable width encoding
Is this data or code? Knowing this will help you understand how your program works. Everything in your program eventually gets reduced to a bunch of bytes. How does the computer keep track of what’s what?
- What’s an instruction?
- What’s data?