Representing numbers
As you know by now, numbers are a computer’s bread and butter, the fundamental basis of everything it does. Whatever information you send to the compiler will eventually become a number. For example, each character within a block of text is represented by a number. You’ll learn more about this in Chapter 3, which delves
into types including strings, the computer term for a block of text.
Images are no exception. In a computer, each image is also represented by a series of numbers. An image is split into many thousands, or even millions, of picture elements called pixels, where each pixel is a solid color. If you look closely at your computer screen, you may be able to make out these blocks. That is unless you have a particularly high-resolution display where the pixels are incredibly small!
Each of these solid color pixels is usually represented by three numbers: one for the amount of red, one for the amount of green and one for the amount of blue. For example, an entirely red pixel would be 100% red, 0% green and 0% blue.
The numbers the CPU works with are notably different from those you are used to. When you deal with numbers in day-to-day life, you work with them in base 10, otherwise known as the decimal system. Having used this numerical system for so long, you intuitively understand how it works. So that you can you can appreciate the CPU’s point of view, consider how base 10 works.
The decimal or base 10 number 423 contains three units, two tens and four hundreds:
In the base 10 system, each digit of a number can have a value of 0, 1, 2, 3, 4, 5, 6, 7, 8 or 9, giving a total of 10 possible values for each digit. Yep, that’s why it’s called base 10!
But the true value of each digit depends on its position within the number. Moving from right to left, each digit gets multiplied by an increasing power of 10. So the multiplier for the far-right position is 10 to the power of 0, which is 1. Moving to the left, the next multiplier is 10 to the power of 1, which is 10. Moving again to the left, the next multiplier is 10 to the power of 2, which is 100. And so on.
This means each digit has a value ten times that of the digit to its right. The number 423 is equal to the following:
(0 1000) + (4 100) + (2 10) + (3 1) = 423
Binary numbers
Because you’ve been trained to operate in base 10, you don’t have to think about how to read most numbers — it feels quite natural. But to a computer, base 10 is way too complicated! Computers are simple-minded, remember? They like to work with base 2.
Base 2 is often called binary, which you’ve likely heard of before. It follows that base 2 has only two options for each digit: 0 or 1.
Almost all modern computers use binary because at the physical level, it’s easiest to handle only two options for each digit. In digital electronic circuitry, which is mostly what comprises a computer, the presence of an electrical voltage is 1 and the absence is 0 — that’s base 2!
Note: There have been computers both real and imagined that use the ternary numeral system, which has three possible values instead of two. Computer scientists, engineers and dedicated hackers continue to explore the possibilities of a base-3 computer. See https://en.wikipedia.org/wiki/ Ternary_computer and http://hackaday.com/tag/ternary-computer/.
Here’s a representation of the base 2 number 1101:
In the base 10 number system, the place values increase by a factor of 10: 1, 10, 100, 1000, etc. In base 2, they increase by a factor of 2: 1, 2, 4, 8, 16, etc. The general rule is to multiply each digit by an increasing power of the base number — in this case, powers of 2 — moving from right to left.
So the far-right digit represents (1 2^0), which is (1 1), which is 1. The next digit to the left represents (0 2^1), which is (0 2), which is 0. In the illustration above, you can see the powers of 2 on top of the blocks.
Put another way, every power of 2 either is (1) or isn’t (0) present as a component of a binary number. The decimal version of a binary number is the sum of all the powers of 2 that make up that number. So the binary number 1101 is equal to:
(1 8) + (1 4) + (0 2) + (1 1) = 13
And if you wanted to convert the base 10 number 423 into binary, you would simply need to break down 423 into its component powers of 2. You would wind up with the following:
(1 256) + (1 128) + (0 64) + (1 32) + (0 16) + (0 8) + (1 *
4) + (1 2) + (1 1) = 423
As you can see by scanning the binary digits in the above equation, the resulting binary number is 110100111. You can prove to yourself that this is equal to 423 by doing the math!
The computer term given to each digit of a binary number is a bit (a contraction of “binary digit”). Eight bits make up a byte. Four bits is called a nibble, a play on words that shows even old school computer scientists had a sense of humor.
A computer’s limited memory means it can normally deal with numbers up to a certain length. Each register, for example, is usually 32 or 64 bits in length, which is why we speak of 32-bit and 64-bit CPUs.
Therefore, a 32-bit CPU can handle a maximum base-number of 4,294,967,295, which is the base 2 number 11111111111111111111111111111111. That is 32 ones— count them!
It’s possible for a computer to handle numbers that are larger than the CPU maximum, but the calculations have to be split up and managed in a special and longer way, much like the long multiplication you performed in school.
Hexadecimal numbers
As you can imagine, working with binary numbers can become quite tedious, because it can take a long time to write or type them. For this reason, in computer programming, we often use another number format known as hexadecimal, or hex for short. This is base 16.
Of course, there aren’t 16 distinct numbers to use for digits; there are only 10. To supplement these, we use the first six letters, a through f. They are equivalent to decimal numbers like so:
• a = 10
• b = 11
• c = 12
• d = 13
• e = 14
• f = 15
Here’s a base 16 example using the same format as before:
Notice first that you can make hexadecimal numbers look like words. That means you can have a little bit of fun. :]
Now the values of each digit refer to powers of 16. In the same way as before, you can convert this number to decimal like so:
(12 4096) + (0 256) + (13 16) + (14 1) = 49374
You translate the letters to their decimal equivalents and then perform the usual calculations.
But why bother with this?
Hexadecimal is important because each hexadecimal digit can represent precisely four binary digits. The binary number 1111 is equivalent to hexadecimal f. It follows that you can simply concatenate the binary digits representing each hexadecimal digit, creating a hexadecimal number that is shorter than its binary or decimal equivalents.
For example, consider the number c0de from above:
c | = | 1100 |
---|---|---|
0 | = | 0000 |
d | = | 1101 |
e | = | 1110 |
This turns out to be rather helpful, given how computers use long 32-bit or 64-bit binary numbers. Recall that the longest 32-bit number in decimal is 4,294,967,295. In hexadecimal, it is ffffffff. That’s much more compact and clear.