Photo by Aleksandar Cvetanovic on Unsplash
Reviewing binary number basics with my wife at 3 am on a Sunday
Before we start: Remember to sign up for the blog! It's free and you'll get awesome content directly to your inbox ๐
Last Saturday, my wife Hannah and I were having dinner with a couple of friends of ours who are both technical people. Inevitably, the oldest CS joke came to the table:
We tech folks at the table shrugged the joke off since we've heard it a bazillion times but Hannah was bothered she didn't get it. For some reason, our conversation ended up not going further into that route and I thought she had forgotten about it by the night's end.
Boy... was I wrong.
In addition to being a political scientist (soon to be a master of political science, mind you), Hannah is just a curious soul and won't let something go until she's fully understood it. To those of you who know us both, you can probably see why we got married in the first place.
Anyway, we arrived home at about midnight that day and I was ready to prepare to get some much-needed sleep. A few minutes after I'd had put on my pajamas along with my Avatar Aang socks (it's cold these days, let me be) and turned off the lights, a whisper was suddenly heard coming from the realm of dreams and nightmares the other side of the bed:
"I... didn't... understand the binary joke.. can you explain it to me?" she said, knowing fully well the geek inside me would never resist the temptation.
"Are you sure? it's super late already " I said, as the voice of reason inside my head tried to defend my sleepy brain.
"Pleaseeee..? " she said, using her well-mastered Puss in Boots' Cute Eyes impression (this might be an exaggeration of mine but no one has to know ๐ ).
How could I refuse such a heartfelt request to rescue a beautiful lady in much-needed geek support?
I couldn't, of course.
And so it began.
By now, my half-awake, half-zombie mind started racing into technical mode to see how I could explain a classical technical joke to someone who isn't technical at all.
A journey into the wonderful world of base 2 numbers
I decided to start with what I remembered most: Converting between regular decimal numbers and binary ones since decimal numbers are at least part of everyone's day-to-day life.
How do numbers and characters familiar to us become electrical currents running inside a plastic board with welded metal on it? And conversely - how do binary numbers are translated to form the apps and websites we use and love? And most importantly: how do they explain the joke after all?
So let's start by converting a regular, decimal number into its binary form. We do that by simply dividing up the number by two until we reach zero as the divisor. Let's start with the number 255 just as an example:
So if you reverse read the remainder of the divisions by two, we get that 255 in decimal form equals 11111111 in binary. We can get that same result if we do the reverse operation as well. This time we won't divide the binary number by the decimal but rather express it as powers of two:
So this is what we call a positional system. Each '1' or '0' in a binary number receives a positional digit in the sum of powers of two which yields the decimal equivalent to that binary number. Note that if instead of a '1' digit we had a '0' one, the respective power of two for that zero wouldn't be included in the resulting sum:
So here lies the secret key to explaining our joke. If you don't know binary, you'll read the "10" in "There are only 10 types of people" in its decimal form and the joke won't make sense. If you read it in binary though, the binary 10 is equal to decimal 2:
Hence the joke now makes sense: There are only two kinds of people, those who know binary and those who don't. You're now part of the first group, so congrats ๐
Cool, so what?
I could have stopped at this point and finally gotten some sleep but of course, I was now too awake to do that. Why is it so important to understand binary though? Sure enough, you've probably always heard of them but at the end of the day, what role do they play in practice?
There are multiple answers to those questions. Files inside a hard drive are represented as streams of binary ones and zeros the computer reads and writes. Images are generated through RGB information in each pixel in a screen that is once again converted to binary at some point, and much more.
But most important to me though is how they allow us to build computers with ever more RAM (random access memory). This is super important since having more memory allows us to build more robust and complex applications. I know - humanity went to the moon with mesmerizing 4kbs of RAM available, but the point applies still. Imagine RAM being much like a street with sequential houses in it and that inside each house you can store some amount of information instead of people:
So for a computer to understand how much RAM it has available, it needs to be able to assign addresses to those many, many individual houses. This is where binary numbers come in: Memory addressing is directly related to how large such numbers are inside a computer. That's because each of those "houses" gets a binary address assigned to it:
"What on earth is happening here?" you might ask.
I know - the 0x000
... numbers can be intimidating but bear with me. They're only another way of representing the same binary numbers we've been talking about. The only thing is that instead of converting binary to decimal numbers, we're converting them to hexadecimal which allows for up to 16 characters to be used to represent numbers:
Anyway - back to our houses. Each of the 0x000...
numbers above represent the address of each house. Knowing the address of any specific house then allows us to retrieve the data inside it instantaneously. Also, we don't need to visit any of the other houses if we already know we're going. We can do that even in a random fashion by visiting one house, then another one that's completely unrelated to the first, and then another one, and so on. Hence, this is where the Random Access Memory name comes from - we're able to access any of the addresses in memory randomly and instantaneously.
The maximum amount of digits in a binary number a computer knows determines how many of our houses it's able to assign addresses to. Have you ever heard of 32-bit and 64-bit computers? This is what those numbers refer to. In a computer that understands binary numbers with 32 digits, we can address up to 2^32 houses, which allows us to store about 4 gigabytes of information. Likewise, 64 digits allow us to address up to 2^64 numbers and store up to 16 exabytes of data. Can you imagine that amount of information all living in a single place?
Going beyond addresses
Good - now we know we can store data inside a memory that's readily accessible and that we can fetch it quickly and easily. A couple of questions arise at this point: What kind of data can we store inside that memory? and how does it end up there?
For the first question - we can essentially store anything we want inside a computer if we can represent that information in binary form.
Photos? Binary.
Movies? Binary.
Bad computer science jokes? Binary as well.
But the way we store a basic type of information always amazes me - floating point numbers. Yes - they should be as simple to store as integers, shouldn't they? Only that they aren't. For example - how do you represent the 10.25 number inside a computer? We can't use the same example we've given above since we now have a fractional part that doesn't fit the way we currently represent numbers in memory.
The solution then is to come up with a new understanding of binary numbers stored inside a computer's memory. We call that IEEE-754, a standard of representation and manipulation of floating-point numbers in computer systems, ensuring consistent behavior across different hardware platforms and programming languages.
This is what a floating point number looks like in that format:
Each binary digit in a sequence representing a floating point number is divided into three sections: a sign, an exponent, and a fraction. You can probably guess it by now, but the sign determines whether the number is positive or negative, the exponent represents the whole part of the number, and the fraction... well, the fractional part of that number. You can find a more in-depth explanation of the whole process here and even play with a few examples if you want to.
A crucial role binary numbers play here is that the IEEE 754 standard predicts two kinds of floating point numbers: 32-bit and 64-bit, just like we were discussing earlier. Keep in mind that at this point we're using those numbers not to address physical memory but rather to operate on the numbers stored inside of said memory. In this case - aren't 32-bit numbers enough for most calculations? The maximum number we can represent in that fashion is 3.4028235 \ 10* followed by 38 zeroes after all.
For sure that's enough for the vast majority of our everyday use cases but highly specialized computing does need even more precision than that, and that's why there's a 64-bit IEEE 754 standard. If you don't believe me, a rocket has exploded exactly because its internal computer could not understand 64-bit but only 16-bit numbers. So big, precise numbers were being converted to much less detailed ones causing conversion errors and ultimately leading the whole rocket to blow up.
Conclusion
At this point, I was super excited but Hannah was barely staying awake (understandably so!). The point here is that even the simplest of things might serve as a valid entry point to discuss much larger and more complex topics. We could go much deeper into this and talk about how processors grab information from RAM to use in calculations or how circuits that hold information inside non-persistent memory work, but that'd make this already long post longer so I'll leave that to another opportunity.
If you made it this far, thank you for staying with me.
I hope you enjoyed it,
Teo.