WORKING WITH BINARY NUMBERS



Name 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0 bit
2 to the power of 27 26 25 24 23 22 21 20
Value 128 64 32 16 8 4 2 1

Table 1: An 8-bit Register

Computers are stupid, they could only understand 2 basic states, on and off. Humans however, are clever creatures and as such have figured out how to represent anything with 1s and 0s. This tutorial will discuss how to represent data using the binary number system.

The most common microcontrollers on the market store data in 8-bit registers (and thus are called 8-bit microcontrollers), Some of us have 64-bit computers, this means that the processor uses 64-bit registers, thus being able to process numbers 8 times bigger then an 8-bit microcontroller.

Ok but what is a register? A register is a set number of 1s and 0s that are used to represent data. From now on we will be working with 8-bit registers unless stated otherwise. An 8-bit register is a chunk of data that can house 8 1s and 0s.

Every register follows the same rules, the minimum number that they can store is 0, and the maximum number they could store is 2register_size. We use an 8 bit register, so we can store 28 values which is 256, since 0 is considered a number that limits our maximum number to 255 (255 is our 256th value).

So lets count in binary, 0, 1, 10, 11, 100, 101, 110, 111 .... get the pattern? Basically, if you have a 1, then the next step is to change that 1 to a 0 and put a 1 in front of it, much like how when we hit 9 we turn that 9 to a 0 and put a 1 in front of it.


BINARY TO DECIMAL:

Now that we know how to count in binary, how do we convert this system into a numbers that we could understand (decimal)? say we have 10010 in binary? Well, look at the table above, and let's throw 10010 into the table we would get:

Name 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0 bit
/ 0 0 0 1 0 0 1 0
2 to the power of 27 26 25 24 23 22 21 20
Value 128 64 32 16 8 4 2 1

Table 2: 10010 within an 8-bit Register

Notice how the bit has a value associated to it. The value of each bit is calculated by using 2 to the power of the bit location, 20 for the 0 bit, 21 for the 1 bit .... etc. An easier way to calculate this is to start at 1 for the 0 bit and multiply by 2 to get the next number.

Lets get back to our example, take the values of all the bits that have a 1 in them and add them together, so 16 + 2 = 18, so 10010 in binary is 18 in decimal.

I have studied computer science and electrical engineering for years, and I still use the above chart to convert numbers (when a calculator is not available) so don't be afraid to use it, every computer science and electrical engineering test that I have taken that require conversion has that table drawn on it somewhere.

NOTE: From now on I will always show decimal values in groups of 8 (because that is the way they appear in the 8 bit register). I will include the leading 0s and I will put a space every 4 sets in order to make it easier to read. So I will write "10010" as "0001 0010".


BINARY TO HEXADECIMAL:

Hopefully you could see the same problem with binary as I can. It's hard to understand what number you're dealing with when you just see a long series of 1's and 0's. Well, again, people are clever, we find solutions to problems. For this one, we invented a numbering system that is much easier to understand called hexadecimal or HEX for short.

Conversion from binary to Hex is simple, split the binary number into groups of 4 and treat each group as its own number and perform the same conversion as we did with binary. So if we us the same numbers as in our previous example (0001 0010) we get 12 in hex:

Name 3 bit 2 bit 1 bit 0 bit 3 bit 2 bit 1 bit 0 bit
/ 0 0 0 1 0 0 1 0
2 to the power of 23 22 21 20 23 22 21 20
Value 8 4 2 1 8 4 2 1

Table 3: 8-bit Register to Hex Conversion

But there is a problem because each set of 4 bits can represent 16 values (24 = 16). So now we need to make up a single digit symbol for 10,11, ... well in hex once we run out of numbers we start using letters, so in hex the number system runs from 0 to F (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F). The best thing about HEX is that it works for all sizes of registers. Take a 16 bit register with the value of 0001 0010 0100 1000, in hex that would be 1248.


DECIMAL, BINARY, HEX AND C:

Now we have 3 systems, so when we see 1000 what is the actual number? The answer is that 1000 decimal, unless stated otherwise numbers always default to decimal. A binary number would be followed by a "b" and a hex number would be followed by a "h" ie. 1000b, 1000h.

The same is true when we program but in C, but we use "0b" in front of the binary number and "0x" in front of a hex number.

    i = 100;      // 100 is stored in i
    i = 0b100;    // 100b is stored in i which is 4 in decimal
    i = 0x100;    // 100h is stored in i which is also 4 in decimal

A lot of programmers tend to think in hex, so hopefully this will not be a surprise for you when you see it used in a program in the future.

Cheers
Q