|
| 1 | +# Binary Code |
| 2 | + |
| 3 | +One of the more mysterious concepts in computer science is binary code. Even though it is a fundamental building block concerning how computers function, programmers today can get away without a deep understanding of how it works. By the end of this lesson, you'll have that advantage! |
| 4 | + |
| 5 | +### Prerequisites |
| 6 | + |
| 7 | +For this lesson you'll need to have _Python 2.7_ installed. If you're on Mac or Linux, this should already be preinstalled on your system. If you're on Windows, you may need to [download it](http://www.python.org/download/releases/2.7.6/). |
| 8 | + |
| 9 | +## Coding Example |
| 10 | + |
| 11 | +Let's jump right into some code. Create a new Python file called `binary_example1.py`. Type this into it: |
| 12 | + |
| 13 | +``` |
| 14 | +num = 1 |
| 15 | +print num |
| 16 | +
|
| 17 | +for i in range(11): |
| 18 | + num = num << 1 |
| 19 | + print number |
| 20 | +``` |
| 21 | + |
| 22 | +Run it, and you'll see that this is what you get: |
| 23 | + |
| 24 | +``` |
| 25 | +$ python binary_example1.py |
| 26 | +1 |
| 27 | +2 |
| 28 | +4 |
| 29 | +8 |
| 30 | +16 |
| 31 | +32 |
| 32 | +64 |
| 33 | +128 |
| 34 | +256 |
| 35 | +512 |
| 36 | +1024 |
| 37 | +2048 |
| 38 | +``` |
| 39 | + |
| 40 | +I bet you're wondering what that `<<` thing does... We’ll get into that in a little while. |
| 41 | + |
| 42 | +__Does anybody recognize those numbers from anywhere?__ |
| 43 | + |
| 44 | +## Game Time |
| 45 | + |
| 46 | +Now, hop over to this game called [2048](http://gabrielecirulli.github.io/2048/). Play it for a little while. The objective is to use the arrow keys to move the numbers and combine (add) the matching ones together. It can be addicting, so don't get too carried away! ;) |
| 47 | + |
| 48 | +After you've played it for a bit, you may start to notice a similarity between the numbers in the game and the Python code we just wrote. |
| 49 | + |
| 50 | +__Why are the numbers in the game the same ones that came out of our Python program?__ |
| 51 | + |
| 52 | +I will give you a hint... Instead of thinking about the game as `2 + 2`, `4 + 4`, `8 + 8`, etc., think about it as `2 * 2`, `2 * 4`, `2 * 8`, and so on. |
| 53 | + |
| 54 | +## 1s and 0s |
| 55 | + |
| 56 | +By now you may be thinking, "I thought we were supposed to be learning about binary code! I thought that was all made up of `1`s and `0`s!" If you _are_ thinking that, you're exactly right! The difference is between how those numbers look to you and how they look to the computer. |
| 57 | + |
| 58 | +__What, then, is binary code?__ |
| 59 | + |
| 60 | +Binary code is what you probably already think it is: sequences of `1`s and `0`s. It might look like `10011001` or `10101010`. But since we are humans, that code doesn't really mean anything to us! Also, why were we playing with `2`s, `4`s, and `8`s when binary is only made up of `0` and `1`? |
| 61 | + |
| 62 | +Let's focus on answering a couple of key questions: |
| 63 | + |
| 64 | +* Why is binary code made up of `1`s and `0`s? |
| 65 | +* What does the binary code mean? |
| 66 | + |
| 67 | +## Why is binary code made up of 1s and 0s? |
| 68 | + |
| 69 | +The answer to this question goes back to how the very first computers where built. The most important piece of the answer is a little device called a **[transistor](http://en.wikipedia.org/wiki/Transistor)**. |
| 70 | + |
| 71 | +A **transistor** is a switch, except transistors also have the ability to amplify the signal that is going into them. Because a transistor is a _switch_, it can either be `OFF` or `ON` (Just like a light switch at home). Because a transistor is an _amplifier_, many of them can be connected together in a circuit without the signal dying. You can put however many transistors you want into a circuit and the signal will still make it to the finish line. |
| 72 | + |
| 73 | +It's not too much of a jump then to see how `0` is like `OFF`, and how `1` is like `ON` (You might have also seen other paired values in programming like `NO`/`YES` or `false`/`true`). This means that a transistor has the ability to _store data_, but it can only store a value of `0` or `1`. That's actually okay, because a computer designer could use as many transistors in a computer as he wants. |
| 74 | + |
| 75 | +So that is the basics of how transistors came to be used in computer hardware. Having a bunch of `0`s and `1`s around may not seem to have an obvious use. We are about to look at how **the ability to store multiple `0`s and `1`s is incredibly powerful.** |
| 76 | + |
| 77 | +## What does the binary code mean? |
| 78 | + |
| 79 | +### Every piece of data has a binary representation |
| 80 | + |
| 81 | +Let's look at `binary_example1.py` again. |
| 82 | + |
| 83 | +``` |
| 84 | +num = 1 |
| 85 | +print num |
| 86 | +
|
| 87 | +for i in range(11): |
| 88 | + num = num << 1 |
| 89 | + print number |
| 90 | +``` |
| 91 | + |
| 92 | +So, about that `<<` thing. `<<` is actually an _operator_ much like `+`, `-`, `*` or `/`. However, while `+-*/` are _arithmetic operators_, `<<` is a _bitwise operator_. It is called **left shift**, and it operates on the _underlying binary representation_ of the number to the left of `<<`. What this implies is that **for every number** (`1`, `2`, `3`, `4`, ...), **there is a binary code equivalent**. |
| 93 | + |
| 94 | +How do we know what that binary code is? Well, `0` and `1` are freebies, because they are already part of the **binary number system** (which is made up of `0`s and `1`s). However, binary code is usually represented in groups of 8. So, the binary representation of `0` is `00000000`, and the binary representation of `1` is `00000001`. |
| 95 | + |
| 96 | +A **bit** is an individual `0` or `1` in the binary code. A group of 8 bits is called an **octet**. A **byte** stores one **octet**, or 8 **bits**. |
| 97 | + |
| 98 | +The **left shift operator** (`<<`) takes the binary version of the number to the left of the operator and _shifts_ all of the **bits** to the left. The number of places to shift is determined by the number to the right of the `<<` operator. So, `num << 1` just means _"shift `num`'s bits `1` place to the left"_. |
| 99 | + |
| 100 | +So throughout our program, the variable `num` is backed by these values: |
| 101 | + |
| 102 | +``` |
| 103 | +00000001 # num = 1 |
| 104 | +00000010 # num = num << 1 |
| 105 | +00000100 # num = num << 1 |
| 106 | +00001000 # num = num << 1 |
| 107 | +00010000 # num = num << 1 |
| 108 | +00100000 # num = num << 1 |
| 109 | +01000000 # num = num << 1 |
| 110 | +10000000 # num = num << 1 |
| 111 | +``` |
| 112 | + |
| 113 | +See how the `1` bit shifts to the left with every cycle of the `for` loop? We can map these **octets** to our program output to see how they match up. |
| 114 | + |
| 115 | +``` |
| 116 | +00000001 # 1 |
| 117 | +00000010 # 2 |
| 118 | +00000100 # 4 |
| 119 | +00001000 # 8 |
| 120 | +00010000 # 16 |
| 121 | +00100000 # 32 |
| 122 | +01000000 # 64 |
| 123 | +10000000 # 128 |
| 124 | +... |
| 125 | +``` |
| 126 | + |
| 127 | +What about `256`, `512`, `1024` and `2048`? Python knows that it needs another **byte** to store those larger numbers, so we get another **octet** to left shift into. |
| 128 | + |
| 129 | +``` |
| 130 | +00000000 00000001 # 1 |
| 131 | +00000000 00000010 # 2 |
| 132 | +00000000 00000100 # 4 |
| 133 | +00000000 00001000 # 8 |
| 134 | +00000000 00010000 # 16 |
| 135 | +00000000 00100000 # 32 |
| 136 | +00000000 01000000 # 64 |
| 137 | +00000000 10000000 # 128 |
| 138 | +00000001 00000000 # 256 |
| 139 | +00000010 00000000 # 512 |
| 140 | +00000100 00000000 # 1024 |
| 141 | +00001000 00000000 # 2048 |
| 142 | +``` |
| 143 | + |
| 144 | +Now we need to understand why the position of the `1` bit determines which number it represents. |
| 145 | + |
| 146 | +## The Binary Number System |
| 147 | + |
| 148 | +Let's make a new Python file and call it `binary_example2.py`. It's going to be a lot like our first example, but we are going to replace the **left shift** with another expression. |
| 149 | + |
| 150 | +``` |
| 151 | +num = 1 |
| 152 | +print num |
| 153 | +
|
| 154 | +for i in range(11): |
| 155 | + num = num * 2 |
| 156 | + print number |
| 157 | +``` |
| 158 | + |
| 159 | +**What do you think this program outputs?** Here's a hint: remember how after we played the _2048_ game I said to think about the numbers as `2 * 2`, `2 * 4`, `2 * 8`, and so on? Lo and behold! |
| 160 | + |
| 161 | +``` |
| 162 | +$ python binary_example2.py |
| 163 | +1 |
| 164 | +2 |
| 165 | +4 |
| 166 | +8 |
| 167 | +16 |
| 168 | +32 |
| 169 | +64 |
| 170 | +128 |
| 171 | +256 |
| 172 | +512 |
| 173 | +1024 |
| 174 | +2048 |
| 175 | +``` |
| 176 | + |
| 177 | +By using a mathematical device called a [**change of base**](http://en.wikipedia.org/wiki/Radix), binary values can be used to express more complex values than `0` and `1`. |
| 178 | + |
| 179 | +#### Take a deep breath, it's time for some math! |
| 180 | + |
| 181 | +Our natural counting system is more precisely called the **decimal system**, and it has a base of `10`. Bases work off of the position of the _digits_ in the number. The number of potential digits in a base is equal to the value of the base, so base 10 has 10 possible digits it can express numbers with. The digits always include `0`. If you count how many numbers are between `0` and `9`, you'll find there are `10`, so `[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]` is the digit set for base 10. |
| 182 | + |
| 183 | +To figure out the decimal value of a number in a different base, the value of each digit is multiplied by the base to the power of the digit's position. Then all those are added together. "To the power of" just means multiplying a number by itself that many times. This is called an __exponent__. |
| 184 | + |
| 185 | +Let's explain the decimal number `123`. We are going to convert it from base 10 to base 10, so the number won't actually change, but breaking it down will help explain the concept: |
| 186 | + |
| 187 | +* 3 is in the 0th positon, 2 is in the 1st position, 1 is in the 2nd position. |
| 188 | +* The value of the 0th digit is `3`, and the base is 10, so its decimal value is `3 * 10 ^ 0`, or `3 * 1`. Any number to the 0th power is `1`. `3 * 1` equals `3` |
| 189 | +* The value of the 1st digit is `2`, so its decimal value is `2 * 10 ^ 1`, or `2 * 10`, which equals `20`. |
| 190 | +* The value of the 2nd digit is `1`, so its decimal value is `1 * 10 ^ 2`, or `1 * 10 * 10`, which equals `100`. |
| 191 | +* Now we add them all together: |
| 192 | + |
| 193 | +``` |
| 194 | + 100 |
| 195 | + 20 |
| 196 | ++ 3 |
| 197 | +---- |
| 198 | + 123 |
| 199 | +```` |
| 200 | +
|
| 201 | +The **binary system** is base 2, which contains only 2 digits including `0`. That only leaves room for one more, the digit `1`. These are our transistors! |
| 202 | +
|
| 203 | +Let's look at an example binary octet, `00101010`, and convert it to decimal: |
| 204 | +
|
| 205 | +* The value of the 0th digit is `1`, and the base is 2, so its decimal value is `0 * 2 ^ 0`, or `0 * 1`, which equals `0`. |
| 206 | +* The value of the 1st digit is `1`, so its decimal value is `1 * 2 ^ 1`, or `1 * 2`, which equals `2`. |
| 207 | +* The value of the 2nd digit is `0`, so its decimal value is `0` since any number times 0 equals 0. |
| 208 | +* The value of the 3rd digit is `1`, so its decimal value is `1 * 2 ^ 3`, or `1 * 2 * 2 * 2`, which equals `8`. |
| 209 | +* The value of the 4th digit is `0` |
| 210 | +* The value of the 5th digit is `1`, so its decimal value is `1 * 2 ^ 5`, or `1 * 2 * 2 * 2 * 2 * 2`, which equals `32`. |
| 211 | +* The value of the 6th and 7th digits are `0` |
| 212 | +* Now we add them all together, and since we are adding we can ignore the `0`s: |
| 213 | +
|
| 214 | +``` |
| 215 | + 32 |
| 216 | + 8 |
| 217 | ++ 2 |
| 218 | +--- |
| 219 | + 42 (the meaning of life, the universe and everything!) |
| 220 | +``` |
| 221 | +
|
| 222 | +# Storing Things Besides Numbers |
| 223 | +
|
| 224 | +So now we know how we can use the **binary number system** to express large numbers with just `1`s and `0`s. Well, even though numbers are useful and all, humans think in terms of words. Raw numbers don't leave us with a way to express readable text in a way that the computer can store. |
| 225 | +
|
| 226 | +Computer scientists were trying to solve this exact problem about 50 years ago. Computers needed to support the uppercase alphabet (26 characters), the lowercase alphabet (26 characters), numerals (10 characters), plus punctuation and special characters. Computers didn't have a lot of storage space at the time, so the scientists needed to figure out a way to fit a way to express those characters in the smallest amount of space per character. |
| 227 | +
|
| 228 | +It turned out that **8 bits** could store 256 different combinations (Binary `11111111` is equal to the decimal number 255), and so eventually **8 bits** became the compromise between space and flexibility for storing a single character. |
| 229 | +
|
| 230 | +So letters on a computer are just an illusion! At least an illusion as far as the computer is concerned. |
| 231 | +
|
| 232 | +Here's our last example, `binary_example3.py`. I am using the `ord()` and `chr()` functions to find the number value for a character, messing with that |
| 233 | +number, then turning it back into a character. |
| 234 | +
|
| 235 | +``` |
| 236 | +letter_a = "A" |
| 237 | +letters = [] |
| 238 | + |
| 239 | +print "UPPER:" |
| 240 | +for i in range(26): |
| 241 | + idx = ord(letter_a) |
| 242 | + new_letter = chr(idx + i) |
| 243 | + letters.append(new_letter) |
| 244 | + print new_letter |
| 245 | + |
| 246 | +print "\nlower:" |
| 247 | +for letter in letters: |
| 248 | + idx = ord(letter) |
| 249 | + shifted = idx + 32 # Why does adding 32 make it lowercase? |
| 250 | + new_letter = chr(shifted) |
| 251 | + print new_letter |
| 252 | +``` |
| 253 | +
|
| 254 | +Run the program and see what it does. What is so significant about adding 32? Well, there is a standard mapping of numbers to characters called |
| 255 | +ASCII. [Check out the table](http://www.asciitable.com/) and see those numbers for yourself. |
| 256 | +
|
| 257 | +# Conclusion |
| 258 | +
|
| 259 | +Now you have a grasp of how computers handle binary code, and how binary code relates to computer data we humans can understand. We have just covered the basics here, and there are other different ways that different types of data are represented in binary. If you _really_ want to melt your brain, |
| 260 | +check out how [floating point numbers](http://en.wikipedia.org/wiki/Floating_point) work! |
0 commit comments