Volume 01 Beginner 5 sub-modules ~25 min read

The Numbers Computers Use

A computer stores every number, letter and colour as a row of bits. This volume shows how: counting and adding in binary, writing long binary numbers briefly in hex, converting between bases by hand, storing negative numbers in two's complement, and the codes - BCD, Gray code and ASCII - that give bits other meanings.

You will learn
  • How binary counting works, and how to read and add binary numbers
  • How hexadecimal and octal shorten long strings of bits
  • How to convert between decimal, binary, hex and octal by hand
  • How two's complement stores negative numbers, and why computers use it
  • What BCD, Gray code and ASCII are, and what each one is for
You need
  • Volume 00 of this course: what a bit is, and how many patterns a group of bits can make.

1.1 Binary: counting with two digits

Binary is counting with just two digits, 0 and 1. Each place is worth twice the place to its right: 1, 2, 4, 8 and so on. A binary number is the sum of the places that hold a 1.

How ordinary numbers work

Every day we count in decimal, with ten digits, 0 to 9. In a number like 407, each place is worth ten times the place to its right:


407 = 4×100 + 0×10 + 7×1 = 407

The number of digits, ten, is called the base. Nothing about ten is special. It is simply how many fingers we have.

Places in binary

Binary works the same way with base 2. There are only two digits, so each place is worth twice the place to its right. For eight bits, the places are worth:


place values: 128 64 32 16 8 4 2 1

To read a binary number, write each place's value under it, then add up the places that hold a 1. The places that hold a 0 add nothing, so you can skip them:


1101 = 1×8 + 1×4 + 0×2 + 1×1 = 13
1101 = 8 + 4 + 1 = 13
10110 = 16 + 4 + 2 = 22
The byte 1101 0110 with the weight of each place above its bit 1 128 1 64 0 32 1 16 0 8 1 4 1 2 0 1 weight bit MSB LSB 128 + 64 + 16 + 4 + 2 = 214
Figure 1.1 - Each box holds one bit, and the number above it is what that place is worth. Add up the places that hold a 1: 128 + 64 + 16 + 4 + 2 = 214.

The rightmost bit is worth 1, the least of any place. It is called the least significant bit, or LSB. The leftmost bit is worth the most, so it is the most significant bit, or MSB.

When a number could be read either way, books write its base as a small number after it. So 11012 = 1310: "one one zero one in binary is thirteen in decimal".

Counting in binary

Decimal Binary
0 0000
1 0001
2 0010
3 0011
4 0100
5 0101
6 0110
7 0111
8 1000
9 1001
10 1010
11 1011
12 1100
13 1101
14 1110
15 1111

Look down the rightmost column: that bit flips at every step. The next bit flips every two steps, and the one after that every four. Volume 08 builds counters that do exactly this.

How big a number fits?

Four bits make 16 patterns, and one of them is 0, so the largest value is 15. The same goes for any number of bits: n bits give 2n patterns, and the largest value is one less.

Bits Patterns Largest value
4 16 15
8 256 255
16 65536 65535

Four bits are called a nibble, and eight bits a byte.

Adding in binary

Binary addition uses the same method as decimal addition, with fewer facts to learn:


0 + 0 = 0; 0 + 1 = 1; 1 + 1 = 10; 1 + 1 + 1 = 11

1 + 1 = 10 is simply "two", written in binary. So you write 0 and carry 1 into the next column, just as 5 + 7 in decimal means writing 2 and carrying 1. Here is 6 + 7, worked from the right:


carry  1 1 0
       0 1 1 0   (6)
     + 0 1 1 1   (7)
       -------
       1 1 0 1   (13)

The carry row shows each carry above the column it goes into. The rightmost column never has a carry into it.

Sometimes the answer needs one bit more than the numbers you added:


carry  1 1 1 0
         1 0 1 1   (11)
     +   0 1 1 0   (6)
       ---------
       1 0 0 0 1   (17)

Two 4-bit numbers gave a 5-bit answer, because 17 is more than 15. Volume 06 builds the circuit that adds, and deals with that extra bit.

Quick check

What is the binary number 1010 in decimal?

Show the answer

Answer: A. The places are worth 8, 4, 2 and 1. The 1s sit in the 8 place and the 2 place, so 1010 is 8 + 2 = 10.

1.2 Hexadecimal and octal

Long strings of bits are hard to read. Hexadecimal, or hex, writes each group of four bits as one digit - 0 to 9, then A to F - so a byte is always exactly two hex digits.

Try reading 110101111010 aloud, or copying it without a slip. Now try D7A. Both are the same number, but one is far easier for people to handle. Computers still work in binary; hex is only a shorter way for us to write it.

Sixteen digits

Hex is base 16, so it needs sixteen digits. After 9 it borrows the letters A to F:

Decimal Binary Hex
0 0000 0
1 0001 1
2 0010 2
3 0011 3
4 0100 4
5 0101 5
6 0110 6
7 0111 7
8 1000 8
9 1001 9
10 1010 A
11 1011 B
12 1100 C
13 1101 D
14 1110 E
15 1111 F

Four bits make exactly 16 patterns, and hex has exactly 16 digits. That match is the whole trick.

Binary to hex

Split the bits into groups of four, starting from the right. Then write each group as one hex digit. If the leftmost group is short, fill it with 0s in front:


10110110 -> 1011 0110 -> B 6
110101111010 -> 1101 0111 1010 -> D 7 A
1011010 -> 0101 1010 -> 5 A

Programmers write 0x in front of a hex number, as in 0xB6, so that nobody mistakes it for decimal. Books often write B616 instead.

Common mistake

Grouping from the left. The groups must start at the right-hand end, because that is where the 1s place is. Group 1011010 from the left and you get the wrong number:


grouped from the left by mistake: 1011 010 -> B 2 = 0xB2 = 178
1011010 = 0x5A = 90

Hex to binary

Going back is just as quick. Each hex digit becomes exactly four bits:


3F -> 0011 1111
C8 -> 1100 1000
7EA -> 0111 1110 1010

Where you meet hex

Colours on web pages are written as three bytes in hex, one each for red, green and blue. The colour #FF8800 is a bright orange:


red FF = 255
green 88 = 136
blue 00 = 0

Memory addresses and the contents of registers are nearly always written in hex too, because each digit maps straight onto four bits.

Octal

Octal is base 8. It does the same job as hex with groups of three bits, and uses only the digits 0 to 7:


101110 -> 101 110 -> 56 (octal) = 46
octal 755 -> 111 101 101

Octal is less common than hex, but you still meet it in file permissions on Linux and macOS. Permission 755 gives the owner read, write and run (111), and everyone else read and run (101).

Quick check

What is 0x2F in binary?

Show the answer

Answer: C. Each hex digit becomes four bits. 2 is 0010 and F is 1111, so 0x2F is 0010 1111.

1.3 Converting between bases

To turn a decimal number into binary, divide it by 2 again and again, and read the remainders from the bottom up. To turn binary or hex into decimal, add up the place values.

Decimal to binary: divide by 2

Divide by 2 and write down the remainder, which is always 0 or 1. Then divide the answer by 2 again. Stop when the answer reaches 0:


13 / 2 = 6 remainder 1
6 / 2 = 3 remainder 0
3 / 2 = 1 remainder 1
1 / 2 = 0 remainder 1
read upwards: 13 = 1101

Why read upwards? The first remainder says whether the number is odd, and only the 1s place can make a number odd. So the first remainder is the rightmost bit, and each later remainder is the next bit to the left.

A bigger example works the same way:


156 / 2 = 78 remainder 0
78 / 2 = 39 remainder 0
39 / 2 = 19 remainder 1
19 / 2 = 9 remainder 1
9 / 2 = 4 remainder 1
4 / 2 = 2 remainder 0
2 / 2 = 1 remainder 0
1 / 2 = 0 remainder 1
read upwards: 156 = 10011100

A shortcut: take away powers of two

For numbers up to a few hundred, it is often quicker to take away the biggest place value that fits, again and again:


156 - 128 = 28
28 - 16 = 12
12 - 8 = 4
4 - 4 = 0
156 = 128 + 16 + 8 + 4 -> 1001 1100

The places you took away get a 1, and every other place gets a 0.

Decimal to hex: divide by 16

The dividing method works for any base. For hex, divide by 16, and write each remainder from 10 to 15 as a letter:


2026 / 16 = 126 remainder 10 (A)
126 / 16 = 7 remainder 14 (E)
7 / 16 = 0 remainder 7 (7)
read upwards: 2026 = 0x7EA

Back to decimal

The places in hex are worth 1, 16, 256, 4096 and so on, each sixteen times the last. Multiply each digit by its place and add:


0x7EA = 7×256 + 14×16 + 10×1 = 2026

Octal and hex, through binary

To convert between octal and hex, go through binary. Write each octal digit as three bits, then regroup the bits in fours:


octal 57 -> 101 111 -> 0010 1111 -> 0x2F
Fractions in binary

Places to the right of the point are worth one half, one quarter, one eighth and so on. To convert a fraction, multiply it by 2 again and again. Each time, the whole-number part is the next bit:


0.625 x 2 = 1.25 -> 1
0.25 x 2 = 0.5 -> 0
0.5 x 2 = 1 -> 1
0.625 = 0.101

Some simple decimal fractions never end in binary. 0.1 is one of them:


0.1 x 2 = 0.2 -> 0
0.2 x 2 = 0.4 -> 0
0.4 x 2 = 0.8 -> 0
0.8 x 2 = 1.6 -> 1
0.6 x 2 = 1.2 -> 1
0.2 x 2 = 0.4 -> 0
0.4 x 2 = 0.8 -> 0
0.8 x 2 = 1.6 -> 1
0.6 x 2 = 1.2 -> 1
0.2 x 2 = 0.4 -> 0
0.1 = 0.0001100110... (it never ends)

A computer has to cut such a fraction off somewhere, so it stores a value very slightly off. That is why many programming languages print this:


0.1 + 0.2 in 64-bit floating point = 0.30000000000000004
Quick check

What is 25 in binary?

Show the answer

Answer: B. 25 = 16 + 8 + 1, so the 16, 8 and 1 places hold 1s: 11001. The first option is the same bits read the wrong way round - the remainders were read downwards instead of upwards.

1.4 Negative numbers: two's complement

A computer has no minus sign, only bits. In two's complement, the top bit simply counts as a negative place: in 8 bits it is worth -128 instead of +128. With that one change, the same adding circuit works for positive and negative numbers.

A number that can be negative is a signed number. Every signed number needs some way to show its sign using nothing but 0s and 1s.

First try: a sign bit

The obvious idea is to keep the top bit for the sign: 0 for plus and 1 for minus. The other bits hold the size. This is called sign-magnitude:


+5 = 0000 0101
-5 = 1000 0101

It has two problems. There are two zeros, which wastes a pattern and makes comparing numbers harder. Worse, ordinary binary addition gives nonsense:


zero twice: +0 = 0000 0000, -0 = 1000 0000
0000 0101 + 1000 0101 = 1000 1010, which sign-magnitude reads as -10

5 + (-5) should be 0, not -10. A computer using sign-magnitude would need extra circuits to add signed numbers.

Two's complement: the top place is negative

Two's complement keeps every place value the same, except the top one, which becomes negative. In 8 bits, the top bit is worth -128:

The byte 1101 0110 read as two's complement, with the top place worth -128 1 −128 1 64 0 32 1 16 0 8 1 4 1 2 0 1 weight bit MSB LSB −128 + 64 + 16 + 4 + 2 = −42
Figure 1.2 - The same eight bits as before, but now the top place is worth -128 instead of +128. Adding the places that hold a 1 gives -128 + 64 + 16 + 4 + 2 = -42.

Read -5 the same way:


-5 = 1111 1011 = -128 + 64 + 32 + 16 + 8 + 2 + 1 = -5

Making a number negative: invert and add 1

You do not have to work out the weights to find a negative number. Start from the positive number, flip every bit, then add 1:


+5 = 0000 0101
invert: 1111 1010
add 1: 1111 1011 = -5

Now add 5 and -5 with the ordinary rules:


carry  1 1 1 1 1 1 1 1
         0 0 0 0 0 1 0 1   (5)
     +   1 1 1 1 1 0 1 1   (-5)
       -----------------
       1 0 0 0 0 0 0 0 0
the ninth bit does not fit in 8 bits and is dropped
keep 8 bits: 0000 0000 = 0

The carry out of the top bit falls off the end, and the answer is exactly 0. That is the whole reason computers use two's complement: one adding circuit handles positive and negative numbers alike.

All sixteen 4-bit patterns

Here is every 4-bit pattern, read as an ordinary unsigned number and as two's complement:

Bits Unsigned Two's complement
0000 0 0
0001 1 1
0010 2 2
0011 3 3
0100 4 4
0101 5 5
0110 6 6
0111 7 7
1000 8 -8
1001 9 -7
1010 10 -6
1011 11 -5
1100 12 -4
1101 13 -3
1110 14 -2
1111 15 -1

Figure 1.3 puts the same patterns round a wheel. Adding 1 always moves one step clockwise, whether the numbers are positive or negative.

Every 4-bit pattern round a wheel, with its two's complement value 0000 0 0001 1 0010 2 0011 3 0100 4 0101 5 0110 6 0111 7 1000 −8 1001 −7 1010 −6 1011 −5 1100 −4 1101 −3 1110 −2 1111 −1 0000 to 0111: 0 to 7 1000 to 1111: −8 to −1 7 + 1 jumps to −8 adding 1 moves one step clockwise
Figure 1.3 - The patterns run clockwise from 0000 at the top, and adding 1 moves one step on. The values inside run 0 to 7, then jump to -8 at the red mark and climb back to -1, just before 0000 again.

Three things stand out:

  1. Every negative number starts with 1, so the top bit still shows the sign at a glance.
  2. There is only one zero. The pattern that sign-magnitude wasted is now -8.
  3. There is one more negative number than positive. -8 has no +8 partner, because +8 does not fit in 4 bits.

How far the numbers go

With n bits, two's complement runs from -2n-1 up to 2n-1 - 1:

Bits Lowest Highest
4 -8 7
8 -128 127
12 -2048 2047
16 -32768 32767

The lowest number is its own odd one out. Negate it with the usual rule and you get it straight back, because its positive partner does not fit:


-128 = 1000 0000; invert: 0111 1111; add 1: 1000 0000 = -128

Sign extension

To copy a signed number into more bits, repeat its top bit into all the new places. This is called sign extension, and it keeps the value the same:


1011 (-5) -> 1111 1011 (-5)
0101 (5) -> 0000 0101 (5)
Common mistake

"To make a number negative, just set its top bit." That is sign-magnitude, not two's complement. In two's complement, 1000 0101 is not -5 at all:


1000 0101 in two's complement = -128 + 4 + 1 = -123

Always invert every bit and add 1.

Two other ways, and why they lost

Besides sign-magnitude there is a third system, ones' complement: to make a number negative, invert every bit and stop there. It also has two zeros. Exam questions sometimes ask about all three, so here they are side by side:

Bits Unsigned Sign-magnitude Ones' complement Two's complement
0000 0 0 0 0
0001 1 1 1 1
0010 2 2 2 2
0011 3 3 3 3
0100 4 4 4 4
0101 5 5 5 5
0110 6 6 6 6
0111 7 7 7 7
1000 8 -0 -7 -8
1001 9 -1 -6 -7
1010 10 -2 -5 -6
1011 11 -3 -4 -5
1100 12 -4 -3 -4
1101 13 -5 -2 -3
1110 14 -6 -1 -2
1111 15 -7 -0 -1

All three agree on the positive numbers. Only two's complement has a single zero and adds correctly with an ordinary adder, which is why every modern computer uses it.

Quick check

What is -1 in 8-bit two's complement?

Show the answer

Answer: D. Start from +1 = 0000 0001, invert it to get 1111 1110, then add 1 to get 1111 1111. The first option is sign-magnitude, and the third is only inverted, which is ones' complement.

1.5 Codes: BCD, Gray code and ASCII

Not every pattern of bits is a number to do sums with. A code gives patterns an agreed meaning: BCD stores decimal digits, Gray code changes one bit at a time, and ASCII stores letters.

BCD: one decimal digit per nibble

Binary-coded decimal, or BCD, keeps each decimal digit in its own four bits:


59 in BCD = 0101 1001; 59 in binary = 0011 1011

BCD is easy to show on a display, because each nibble drives one digit. Clocks, meters and calculators use it. The price is space. Six of the sixteen nibble patterns are never used, and big numbers need more bits:


never used in BCD: 1010 1011 1100 1101 1110 1111
999 in BCD = 1001 1001 1001 (12 bits); in binary = 1111100111 (10 bits)

Gray code: one bit at a time

In ordinary binary, some steps change several bits at once. Going from 3 to 4, all three bits change. In Gray code, every step changes exactly one bit:

Count Binary Gray code
0 000 000
1 001 001
2 010 011
3 011 010
4 100 110
5 101 111
6 110 101
7 111 100
Counting from 0 to 7 in binary (b2 b1 b0) and in Gray code (g2 g1 g0) count 0 1 2 3 4 5 6 7 b2 b1 b0 g2 g1 g0
Figure 1.4 - Between 3 and 4, all three binary bits change at once. In Gray code, only one bit changes at every step - even from 7 back round to 0.

bits that change at each step, binary: 1 2 1 3 1 2 1 3
bits that change at each step, Gray:   1 1 1 1 1 1 1 1

Why does it matter? Picture a sensor that reads the position of a turning knob. If it reads while the position is changing from 3 to 4 in binary, some bits may have changed and others not yet. The reading could be any of the eight values. In Gray code only one bit moves, so a reading taken mid-change is either the old value or the new one:


binary 011 -> 100 changes 3 bits; Gray 010 -> 110 changes 1

To turn binary into Gray code, copy the first bit. Then compare each pair of neighbouring binary bits: the same gives 0 and different gives 1.


binary 1011 -> Gray 1110
first bit copied: 1
1 and 0: differ -> 1
0 and 1: differ -> 1
1 and 1: same -> 0

To go back, copy the first bit again. Then compare each Gray bit with the binary bit you have just worked out: the same gives 0 and different gives 1.


Gray 1110 -> binary 1011
first bit copied: 1
Gray bit 1, binary bit before it 1: same -> 0
Gray bit 1, binary bit before it 0: differ -> 1
Gray bit 0, binary bit before it 1: differ -> 1

"Same gives 0, different gives 1" is a rule you will meet again. Volume 02 turns it into a gate.

ASCII: letters as numbers

To store text, every character needs a number. ASCII is the standard code for English letters, digits and punctuation. It uses 7 bits, which make 128 codes:

Character Decimal Hex Binary (7 bits)
A 65 41 100 0001
B 66 42 100 0010
Z 90 5A 101 1010
a 97 61 110 0001
b 98 62 110 0010
0 48 30 011 0000
9 57 39 011 1001
space 32 20 010 0000

The code was laid out with care. Capital and small letters differ by 32, which is one bit. The digit characters start at 0x30, so taking 0x30 away turns a digit character into its value:


A = 1000001, a = 1100001: they differ by 32, one bit
'7' = 0x37; take away 0x30 -> 7
"Hi" = 0x48 0x69

A parity bit

A byte has room for 8 bits, but ASCII needs only 7. The spare bit can be a parity bit, chosen to make the number of 1s even. If any single bit is flipped on the way, the count of 1s turns odd, and the receiver knows something went wrong:


A = 1000001: 2 ones -> parity bit 0 -> 01000001
C = 1000011: 3 ones -> parity bit 1 -> 11000011
Remember

The same bits can mean different things. Bits do not carry their meaning with them - the circuit reading them decides:


0100 0001: unsigned 65, ASCII 'A', BCD 41
Quick check

Which code changes exactly one bit between each value and the next?

Show the answer

Answer: C. Gray code is built so that neighbouring values differ in exactly one bit, including the wrap from the last value back to the first. That is what makes it safe to read while it is changing.

What you learned

Key words from this volume

Every word below has a plain-English entry in the glossary.

Practice

Practice 1

200 in binary and hex

Convert 200 to binary by repeated division. Then write it in hex.

Show the solution

200 / 2 = 100 remainder 0
100 / 2 = 50 remainder 0
50 / 2 = 25 remainder 0
25 / 2 = 12 remainder 1
12 / 2 = 6 remainder 0
6 / 2 = 3 remainder 0
3 / 2 = 1 remainder 1
1 / 2 = 0 remainder 1

Reading the remainders upwards gives 1100 1000. Split into nibbles, 1100 is C and 1000 is 8:


200 = 1100 1000 = 0xC8
Practice 2

A hex number to decimal

What is 0x3A7 in decimal?

Show the solution

The places in hex are worth 256, 16 and 1, and A is 10:


0x3A7 = 3×256 + 10×16 + 7×1 = 935
Practice 3

Two's complement both ways

Write -100 as an 8-bit two's complement number. Then say what the 8-bit two's complement number 1110 0110 is in decimal.

Show the solution

To find -100, start from +100, invert every bit and add 1:


-100: +100 = 0110 0100; invert: 1001 1011; add 1: 1001 1100

To read 1110 0110, remember that the top place is worth -128, then add the rest:


1110 0110 = -128 + 64 + 32 + 4 + 2 = -26

A quick check: the top bit is 1, so the answer had to be negative.

Practice 4

A year in BCD

Write 2026 in BCD and in binary. How many bits does each need?

Show the solution

2026 in BCD = 0010 0000 0010 0110; in binary = 111 1110 1010 (11 bits)

BCD needs one nibble per decimal digit: 4 digits, so 16 bits. Binary needs only 11 bits. BCD is easier to display, and binary is smaller.

Practice 5

Thirteen in Gray code

Write 13 in binary, then turn it into Gray code.

Show the solution

13 = 8 + 4 + 1, so in binary it is 1101. Copy the first bit, 1. Then compare neighbours: 1 and 1 are the same (0), 1 and 0 differ (1), 0 and 1 differ (1):


13 = 1101 in binary = 1011 in Gray code
Practice 6

How far does 12 bits go?

An analogue-to-digital converter gives a 12-bit two's complement result. What are the lowest and highest values it can report?

Show the solution

With n bits, two's complement runs from -2n-1 to 2n-1 - 1. For 12 bits, the top place is worth 2048:


12 bits, signed: -2048 to 2047

Interview corner

Interview question 1

Why two's complement?

"Why do computers store negative numbers in two's complement?"

Show the solution

"Because then one ordinary adder handles positive and negative numbers alike. Adding 5 and -5 in two's complement gives 1 0000 0000 in 8 bits, and when the carry out of the top is dropped the answer is exactly zero. Sign-magnitude would need extra circuits, and it has two zeros.

Two's complement also keeps the sign visible: every negative number has a 1 in its top bit. The one oddity is that the range is lopsided - 8 bits run from -128 to 127 - so the lowest number has no positive partner."

Interview question 2

A quick way to find a negative number

"How would you write -5 in 8-bit two's complement without inverting bits?"

Show the solution

"Take it away from 2 to the power 8, which is 256. That gives 251, and 251 in binary is the answer:


another way: 256 - 5 = 251 = 1111 1011

It gives the same pattern as inverting and adding 1, because inverting a byte is the same as taking it away from 255."

Volume 02 puts these bits to work: it meets the seven logic gates and the rules each one follows.