Easier to read with cream paper, a tint, more contrast or larger text? Choose your colours and text, once, for every page.

Free lesson

Storing negative numbers and fractions

After this lesson: I can store negative and fractional numbers.

50 min lesson7 commandsCompilers and computer architecture lab: gcc, flex, bison and RISC-V in one VM

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

WordWhat it means
Two's complementthe usual way to store negative whole numbers in bits
Most significant bitthe leftmost bit, worth the most
Overflowan answer too big for the bits that hold it
Fixed pointa number whose point always sits in the same place
Floating pointa number stored as digits and a power that moves the point
Rounding errora 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

BitsRead as 0 to 255Read as two's complementHow it adds up
00000011332 + 1
0111111112712764 + 32 + 16 + 8 + 4 + 2 + 1
10000000128-128-128
11111010250-6-128 + 64 + 32 + 16 + 8 + 2
11111111255-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

StepBits
Write 600000110
Flip every bit11111001
Add one11111010

The cells students fill in are left blank in this preview.

Go to the arch folder

Command
cd ~/arch

Shown 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

Command
printf 'int main(void) { return -6; }\n' > minus.c

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Compile it

Command
gcc minus.c -o minus

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Run it

Command
./minus

Shown 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

Command
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 value8421.1/21/41/81/16
Bit0110.1000
Worth0420.1/2000

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

Command
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

Command
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.

About this lab and its source: Compilers and computer architecture lab: gcc, flex, bison and RISC-V in one VM

Teaching a class? Set this module for your students with a teacher guide, marked assignments and a lab for every student.