10 Ways to Learn Binary

David Rea
5 min readJan 16, 2020

--

There are 10 kinds of people…those who count in binary, and those who do not.

So goes the old programmer’s joke. Should you (where ‘you’ is a new-ish programmer) learn to count in binary? And hexadecimal? And octal?

Which reminds me of another programmer’s joke:

Why do programmer’s forget the difference between Christmas and Halloween?

Because OCT 31 is the same as DEC 25.

Um…get it? The number 31, written in octal, or base-8, has the same value as the number as 25 written in decimal, or base-10. Both are stored in one byte of computer memory thus: 000011001. That’s binary, or base-2.

So, getting back to our question, should learn these number systems in order to program?

You probably don’t need to, unless you are taking a class or standardized test in which you will be required to convert between number systems. But you can have a long, happy career or hobby as a programmer and never actually need to know such things.

The most common place to encounter alternative number systems now…other than totally artificial exam questions…is in specifying color. If you’ve created any web pages, and especially if you’ve poked around in CSS, you may have seen something that looks like this:

background-color: #8b4513;

That funny looking word/number thing, #8b4513 is hexadecimal for the number we humans would probably write as 9127187. (The hash tag, #, often denotes hexadecimal numbers. We’ll use that notation from here on for clarity.)

There are endless tutorials on the internet for figuring out the how of that conversion, so we won’t go into that. But why? Why do we have to make up a whole new counting system? Why not just write 9127187?

This number represents three different values: the red, green, and blue components of the color. #8b is the red, #45 is the green, and #13 is the blue. In decimal those values are 139, 69, and 19.

There’s your first clue about why hexadecimal is better: nowhere in 9127187 do you see the numbers 139, 69, and 19. You probably can’t (and if you can, you have a promising career in rocket surgery) look at 9127187 and say, “Oh, right….139, 69, and 19.” But you look at #8b4513 and the three separate numbers are right there in front of your eyes.

And here’s a cool trick you can do with that: let’s say you want to change the values, like setting the green to 0. In hex that would simply be #8b0013. That is, you subtract out the #004500. That number in decimal is 9109523.

Doh.

What’s going on here, if you haven’t figured it out, is pretty straightforward. Computers count in binary, where each “bit” is a 1 or a 0, and they address memory in chunks of 8 bits. That is, the difference between memory address x and memory address x + 1 is 8 bits.

The problem with binary is that numbers are really long. 8b0013 in binary is b100010110100010100010011, which gets stored in three contiguous bytes as: 10001011|01000101|00010011. But that’s hard to remember/read. So programmers took advantage of a neat math trick: if you convert a number from base a to base b, where b is a raised to the n, each digit in base-b represents exactly n digits in base-a.

Since 16 is 2⁴, each digit in hexadecimal represents exactly 4 digits in binary. So every byte, which is 8 bits, is represented by exactly 2 hexadecimal digits.

If you’ve heard the term “machine language”, it refers to the actual instructions, way down in the basement of your computer, that the computer understands. “Back in the day” this is how you would program a computer. Writing numerical instructions. The first chunk of 1’s and 0’s would tell the computer which instruction to execute, by number, and the next few chunks would be the arguments to the instruction, such as which numbers or memory addresses or registers (special memory locations on the CPU itself) to use. Similar to our red, green, blue example, these binary values were lumped into one big number, which the CPU treats as distinct numbers.

But reading all those 1’s and zeroes was hard, so programmers wrote tools that let them edit in hexadecimal instead. Here’s what a (modern) “hex editor” looks like:

The middle part of the editor shows rows of 16 bytes, each represented by a 2-digit hex number.

The blue numbers on the left count the bytes. A file is being edited, but these numbers will become memory addresses when the program is run. Notice that the numbers increase in the 10’s column only, which is really the 16’s column because we’re counting in hex.

(The righthand area of the editor shows the text, or ASCII, values. This is useful if, and pretty much only if, you are including text in your programs. Even veteran programmers struggle to turn hexadecimal values into the alphabet in their heads.)

You will probably never have to write or edit code using a hex editor. Modern languages are written in much easier to read formats, and then either compiled or interpreted. Compiled languages (like C) are converted into machine language and then stored that way, whereas interpreted languages (like Python) are left in their original format, and a piece of software called the “interpreter” generates machine instructions on the fly whenever you run them.

So…

If you still want to (or have to) learn these alternative number systems, there are basically 10 ways. (Hopefully you caught that joke.):

  1. You can do it the way most courses do, which is teach the conversion rules, then make you do pointless conversions on paper until you master it.
  2. Or you learn it by using it. That is, write code.

(By the way, I tried to number those two ways 0 and 1, but Medium’s auto-list feature doesn’t let me start with 0.)

If you want to do it the second way, here are some ideas for programming projects:

  1. Write a function that takes a decimal number as input, and outputs binary.
  2. Write the reverse function.
  3. Do it for hexadecimal.
  4. Write a function that takes three inputs: a number, and two bases. Output the number converted from the first base to the second base. (For example, if you input 25, 10, and 8, it converts 25 from decimal to octal and outputs 31.)
  5. Write a function that takes two stings of text. The first string is a message to be encrypted. The second string are the “digits” of a number base. For example “abcde” is base-5, with the digits a = 0, b = 1, c = 2, d = 3, e = 4. Convert each letter into it’s ascii number, but written in the new base. Using our example, the letter ‘A’ is 65 in ASCII, which is 230 in base-5, which is “cda” in our new base. So each ‘A’ gets replaced by “cda”.
  6. Write a function that reverses #5. Better yet, work with a friend and each of you try to reverse the other’s #5.

Here’s a question to ponder: if you had a message output from #5, but did not know what the digits of the base were, or what order they were in, or even what base it was in, would it be possible to “crack” the encryption? How would you go about it?

--

--