Minus eighteen in the freezer
A shop freezer shows -18 °C on its screen. A banking app shows £12.50 in your account.
Last lesson, a byte held 0 to 255. There was no minus sign and no point. So how does a computer store a number below zero, or a number with a part after the point?
By the end of this lesson
Note
I can store negative and fractional numbers.
Key words
| Word | What it means |
|---|---|
| Two's complement | the usual way to store negative whole numbers in bits |
| Most significant bit | the leftmost bit, worth the most |
| Overflow | an answer too big for the bits that hold it |
| Fixed point | a number whose point always sits in the same place |
| Floating point | a number stored as digits and a power that moves the point |
| Rounding error | a small difference because a value cannot be stored exactly |
The cells students fill in are left blank in this preview.
Before you start
Note
Press Start the lab on the bar at the top and wait for the machine to say it is running. Each Run button types its command into the machine's terminal, one after another.
The top bit counts as negative
In two's complement the leftmost bit of a byte is worth -128, not 128. The other seven bits keep their usual values.
So a byte that starts with 0 is zero or positive. A byte that starts with 1 is negative. One byte now holds -128 to 127, still 256 different numbers.
Worked example: one byte read two ways
| Bits | Read as 0 to 255 | Read as two's complement | How it adds up |
|---|---|---|---|
| 00000011 | 3 | 3 | 2 + 1 |
| 01111111 | 127 | 127 | 64 + 32 + 16 + 8 + 4 + 2 + 1 |
| 10000000 | 128 | -128 | -128 |
| 11111010 | 250 | -6 | -128 + 64 + 32 + 16 + 8 + 2 |
| 11111111 | 255 | -1 | -128 + 127 |
The cells students fill in are left blank in this preview.
Flip the bits, then add one
There is a quick way to write a negative number. Write the positive number in eight bits. Flip every bit, so 0 becomes 1 and 1 becomes 0. Then add one.
The same steps turn a negative number back into its positive.
Worked example: writing -6
| Step | Bits |
|---|---|
| Write 6 | 00000110 |
| Flip every bit | 11111001 |
| Add one | 11111010 |
The cells students fill in are left blank in this preview.
Go to the arch folder
cd ~/archShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Write a C program that returns -6
printf 'int main(void) { return -6; }\n' > minus.cShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Compile it
gcc minus.c -o minusShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Run it
./minusShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Ask the shell what it returned
echo $?Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
A common mistake
Warning
Many people think the bits themselves say a number is negative. They do not. The program handed back -6 as the bits 11111010. The shell reads those bits as 0 to 255, so it printed 250. The same bits mean -6 or 250, depending on who reads them.
Fixed point keeps the point still
Money is easy to get wrong with fractions. Many programs store it in pence instead: £12.50 becomes 1250. Every sum is then whole numbers, which are exact.
Binary can do the same. Choose a place for the point. Places after it are worth a half, a quarter, an eighth and so on.
Worked example: 6.5 in fixed point
| Place value | 8 | 4 | 2 | 1 | . | 1/2 | 1/4 | 1/8 | 1/16 |
|---|---|---|---|---|---|---|---|---|---|
| Bit | 0 | 1 | 1 | 0 | . | 1 | 0 | 0 | 0 |
| Worth | 0 | 4 | 2 | 0 | . | 1/2 | 0 | 0 | 0 |
The cells students fill in are left blank in this preview.
Floating point moves the point
Fixed point cannot hold a very big and a very small number in the same bits. Floating point stores the digits and a power separately, like 6.5 written as 0.65 × 10.
Most fractions, such as 0.1, have no exact binary form. They are stored very close, but not exactly.
Add 0.1 and 0.2
python3 -c "print(0.1 + 0.2)"Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
See what 0.1 really holds
python3 -c "print(format(0.1, '.20f'))"Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Going further: sixteen bits
A game stores a player's score in 16 bits of two's complement. What is the biggest score it can hold, and the smallest?
Use the same idea as the byte: the top bit is worth minus the value it would usually have. Then say what happens to a score at the top that gains one more point.