Skip to content

← Data and representation

Data in Depth

Unit 2 · Data and representation

Hide the stories, facts, photos, activities and interactives, for revising before an exam
In this unit 11 sections
  1. Number systems
  2. From any base to decimal
  3. From decimal to any base
  4. Shortcuts through binary: hex and octal
  5. Binary arithmetic
  6. Negative numbers
  7. Characters and Unicode
  8. How big is a file?
  9. Compression
  10. In short
  11. Exercise

Take a photo of Nyatapola on a phone, and the file is about 3 MB. Download a four-minute song, and it is about 4 MB. Yet in Grade 7 you worked out that the photo’s pixels need about 34 MB, and a four-minute song stored the way a CD stores it about 40 MB. Where did the other 30-odd megabytes go?

To answer that, this unit looks at data more closely than before. You will count in bases other than ten, including hexadecimal, which you met in Grade 8’s web colors, and convert between them the way the SEE asks. You will subtract and multiply in binary, and store negative numbers. You will see exactly how Unicode turns a Nepali letter into bytes, work out how big a picture or a sound must be, and then find out how files are compressed: squeezed into fewer bytes, sometimes keeping every bit, sometimes throwing away what your eyes and ears would never miss.

Number systems

Count the momos on a plate and you use ten digits, 0 to 9. After 9 you have run out, so you write 10: one ten and no ones. That is the decimal number system. A number system is a way of writing numbers with a fixed set of digits and a rule for what each place is worth.

The number of digits a system uses is its base, also called its radix. Decimal has base 10. In Grades 6 and 7 you counted in binary, base 2, with only 0 and 1. Two more bases are used in computing:

  • Octal, base 8, with the eight digits 0 to 7.
  • Hexadecimal (often just hex), base 16. It needs sixteen digits, so after 0 to 9 it uses the letters A to F for the values 10 to 15.
Number system Base Digits used
binary 2 0, 1
octal 8 0, 1, 2, 3, 4, 5, 6, 7
decimal 10 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
hexadecimal 16 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F
Hexadecimal digit A B C D E F
Its value 10 11 12 13 14 15

Place values are powers of the base

In every one of these systems, a digit’s worth depends on its place. The place on the right is worth 1; each place to the left is worth base times the place before it. So the places are the powers of the base: base⁰ = 1, base¹, base², base³ and so on.

Base Place values, from the right
10 10⁰ = 1, 10¹ = 10, 10² = 100, 10³ = 1,000
2 2⁰ = 1, 2¹ = 2, 2² = 4, 2³ = 8, 2⁴ = 16 …
8 8⁰ = 1, 8¹ = 8, 8² = 64, 8³ = 512
16 16⁰ = 1, 16¹ = 16, 16² = 256, 16³ = 4,096

So the decimal number 719 is

719=7×102+1×101+9×100=700+10+9 719 = 7 \times 10^2 + 1 \times 10^1 + 9 \times 10^0 = 700 + 10 + 9

The same digits mean different numbers in different bases: 101 is a hundred and one in decimal, but five in binary, sixty-five in octal and two hundred and fifty-seven in hex. So when bases are mixed, the base is written as a small number after the brackets: (101)₂, (101)₈, (101)₁₀, (101)₁₆. Programs write it in front instead: Python reads 0b101 as binary, 0o101 as octal and 0x101 as hex.

What is the base (radix) of the hexadecimal number system?

Pick an answer to see why.

Which of these is not a correct octal number?

Pick an answer to see why.

From any base to decimal

To change a number in any base into decimal, do what you did for binary in Grade 6: write the place values over the digits, multiply each digit by its place value, and add.

From decimal to any base

In Grade 7 you changed a number into binary by keeping halving and reading the remainders from the bottom up. The same method works for every base: keep dividing by the base.

  1. Divide the decimal number by the base. Write down the remainder.
  2. Divide the quotient (the answer) by the base again, and write down that remainder.
  3. Carry on until the quotient is 0.
  4. Read the remainders from the last to the first (bottom to top). In hex, write a remainder of 10 to 15 as A to F.

Why it works: the first remainder is what is left over after taking out every whole lot of the base, which is exactly the ones digit. Dividing then moves every digit one place to the right, so the next remainder is the next digit, and so on. The digits come out right-hand end first, so you read them upwards.

Try it

Divide and read upwards

Type a number and choose a base. The divisions are written as the short ladder used in exams: the base on the left, each quotient under the number it came from, with its remainder beside it. The place values underneath turn the answer back into decimal. Work the exercise on paper first, then check it here.

8 345
8 43 1
8 5 3
0 5

Read the remainders upwards, from the bottom.

Place 8²
64
8¹
8
8⁰
1
Digit 531 Worth 320241
Place 0
0
0
0
0
0
0
0
0
0
0
0
Digit 000000 Worth 000000
Place 0
0
0
0
0
0
8²
64
8¹
8
8⁰
1
Digit 000 531 Worth 000 320241
Change it to base
Answer
(345)₁₀ = (531)₈
Check
the Worth row adds up to 345

In changing (88)₁₀ to hexadecimal, 88 ÷ 16 = 5 remainder 8, and 5 ÷ 16 = 0 remainder 5. What is the answer?

Pick an answer to see why.

Python has these conversions built in. bin(), oct() and hex() give a number in binary, octal and hex as text, with the prefixes you saw above, and int() with a second number reads text in that base. Press Run.

print(bin(46), oct(345), hex(540))print(int("10011", 2), int("157", 8), int("1AC", 16))

Output

0b101110 0o531 0x21c19 111 428

Here is the dividing method written out, so you can see that it is just Grade 8’s // and % in a loop. Change n and base and run it again.

digits = "0123456789ABCDEF"n = 540base = 16answer = ""while n > 0:    r = n % base    answer = digits[r] + answer    n = n // baseprint(answer)

Output

21C

n % base is the remainder and n // base the quotient. Each new digit goes on the front of answer, so the digits end up in the right order without reading anything upwards. digits[r] picks the character at position r of the text: position 12 is C.

Shortcuts through binary: hex and octal

Why do computer people bother with hex and octal at all? Because they are shorthand for binary.

Look at the numbers 16 and 8. 16 = 2⁴, so one hex digit holds exactly what four bits hold: from 0000 (0) to 1111 (F). And 8 = 2³, so one octal digit is exactly three bits: 000 (0) to 111 (7). That means you can change between binary and hex, or binary and octal, without going through decimal at all, a few bits at a time.

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

Binary to hex: split the bits into groups of four, starting from the right. If the last group on the left is short, fill it with 0s in front (they change nothing). Write each group as one hex digit.

Hex to binary: write each hex digit as four bits.

Binary to octal, octal to binary: the same, with groups of three.

Try it

Bits in groups

Tap the bits. Choose Hex to group them in fours, or Octal to group them in threes, and read each group as one digit. Notice the groups always start from the right.

B 5
Binary
(10110101)₂
Hexadecimal
(B5)₁₆
Decimal
(181)₁₀

Each group of four bits, counted from the right, is one hex digit, from 0000 = 0 to 1111 = F.

Each group of three bits, counted from the right, is one octal digit, from 000 = 0 to 111 = 7. A short group on the left is filled with 0s.

Where you will see hex

A byte is 8 bits, which is exactly two hex digits: 00 to FF (0 to 255). Hex is so much shorter than binary, and so much easier to split into bytes than decimal, that it is used wherever people need to read the bytes themselves:

  • Colors on the web. In Grade 8 you wrote #8b1a1a for a dark red. Now you can read it: three bytes in hex, red 8B = 8 × 16 + 11 = 139, green 1A = 26, blue 1A = 26. #FFFFFF is white, all three at 255.
  • Unicode. Characters are numbered in hex: न is U+0928 (below).
  • Network cards. Every Wi-Fi and network card has a MAC address of six bytes, written in hex like 3C:22:FB:7A:91:0E. You will meet it in Unit 5.
  • Memory addresses and error codes. When a program crashes, the message often names a place in memory or an error number in hex, such as 0x80070005.

How many bits does one hexadecimal digit stand for?

Pick an answer to see why.

Binary arithmetic

Adding

You learned to add in binary in Grade 7 Grade 7: Adding in binary: add columns from the right, with 1 + 1 = 10 (write 0, carry 1) and 1 + 1 + 1 = 11 (write 1, carry 1). Exam questions often add numbers of different lengths: line them up on the right, as you would in decimal.

Subtracting

Subtraction also works in columns from the right, as in decimal. Three columns are easy: 0 − 0 = 0, 1 − 0 = 1, 1 − 1 = 0. The hard one is 0 − 1: you must borrow from the next column on the left.

In decimal, a borrowed 1 from the tens is worth ten ones. In binary, a borrowed 1 from the next column is worth two of this column. So 0 − 1 becomes (2 − 1) = 1, and the column you borrowed from goes down by 1.

A B A − B
0 0 0
1 0 1
1 1 0
0 1 1, borrowing 1 from the next column

Multiplying

Multiplying is the easiest of all, because there are only two times tables: anything × 0 = 0, and anything × 1 = itself. So long multiplication in binary is just copying and shifting: for each 1 in the bottom number, write the top number, moved left one place for each place along; then add.

Notice the shifted line: moving a binary number one place left (putting a 0 on the right) doubles it, just as putting a 0 on the right of a decimal number multiplies it by ten. Processors use this all the time: shifting bits is one of the fastest things they do.

What is (1101)₂ − (110)₂?

Pick an answer to see why.

What is (110)₂ × (10)₂?

Pick an answer to see why.

Negative numbers

A thermometer in Jumla in January reads −10 °C. A shop’s account can go below zero. A game character can walk left, a negative step. A computer must store negative numbers too, but it has no minus sign: only bits.

A sign bit

The first idea is to use the left-hand bit of a byte as a sign: 0 for plus, 1 for minus, and the other 7 bits for the size. This is called sign and magnitude. +5 is 00000101 and −5 is 10000101.

It is easy to read, but it has two problems. There are two zeros, 00000000 (+0) and 10000000 (−0). Worse, ordinary binary addition gives wrong answers: 5 + (−5) should be 0, but 00000101 + 10000101 = 10001010, which reads as −10. A computer using it would need separate circuits for adding and subtracting.

Two’s complement

Nearly every computer today uses a cleverer way, called two’s complement. In an 8-bit two’s complement number, the left-hand bit is worth −128 instead of +128. All the others keep their usual values.

−128 64 32 16 8 4 2 1

So 11111011 is −128 + 64 + 32 + 16 + 8 + 2 + 1 = −128 + 123 = −5. Any number with a 1 on the left is negative (no other bits can add up to 128), and the numbers run from 10000000 = −128 to 01111111 = +127.

Try it

The left bit is worth −128

Type a number from −128 to 127, or tap the bulbs. Which bulb makes a number negative? What are the biggest and smallest numbers you can make? What is 11111111?

Binary
11111011
Number
−5

−5 = −128 + 64 + 32 + 16 + 8 + 2 + 1

Tap a bulb to switch it on (1) or off (0).

The left bit is worth −128: with it on, the number is negative. The other bits add their place values to −128.

0 and then all 1s: 127, the biggest number 8 bits can show this way. Add 1 and it becomes −128.

Each bit that is on adds its place value to the number. A bit that is off adds nothing.

Adding 1: the bit worth 1 was off, so it simply came on.

Adding 1: the bits on the right that were on went off, and the next bit came on. That is a carry, like 9 + 1 = 10.

All 8 bits are on: 255, the biggest number 8 bits can show. To go higher you need one more bit.

Yes, that is one of the numbers to make. Now try another.

You made every number in the row.

A new pattern! Keep switching to find the others.

You have found that pattern already.

You found them all: 8 bits make 16 different patterns.

Answer

To write a negative number in two’s complement, there is a quick method:

  1. Write the positive number in 8 bits.
  2. Flip every bit: 0 becomes 1 and 1 becomes 0.
  3. Add 1.

The same three steps also turn a negative number back into its positive: flip 11100010 to 00011101, add 1, and you get 00011110, which is 30.

Subtracting by adding

Here is why two’s complement won. To work out 45 − 30, a computer works out 45 + (−30) with the very same adding circuit it uses for every sum (the adder of Unit 1). No separate subtracting circuit is needed.

Try it

Subtracting by adding

The first number is 45 and the second is −30, in two’s complement. Press Add column by column. A 1 is carried off the left end: what happens to it, and is the answer right? Then try 100 + 50.

−1286432168421 1 11 + 1 00001111
In decimal
45 + (−30) = 15
Answer in 8 bits
15

Tap the bits to change the two numbers. Each column is added like on paper: 1 + 1 = 10, so write 0 and carry 1.

The carry off the left end is dropped, and that is fine: in two’s complement the 8 bits left, 15, are the right answer.

The answer should be 15, but 8 bits only go from −128 to 127. It wrapped round to 15: overflow.

Column worth 256: 0 + 0 = 0. Write 0, nothing to carry.

Column worth 256: the bits add up to 1. Write 1, nothing to carry.

Column worth 256: 1 + 1 = 2, which is 10 in binary. Write 0, carry 1 to the next column.

Column worth 256: 1 + 1 + the carried 1 = 3, which is 11 in binary. Write 1, carry 1.

What you should see

Now you can see why the Gangnam Style view counter of Unit 1 stopped at 2,147,483,647. A signed 32-bit number is two’s complement: its left bit is worth −2³¹, so its biggest value is a 0 followed by 31 ones, 2³¹ − 1. One more view would have carried into the left bit and turned the count into −2,147,483,648.

What is −1 in 8-bit two’s complement?

Pick an answer to see why.

Characters and Unicode

In Grade 7 you saw that every character is stored as a number, its code point in Unicode, and that UTF-8 stores English letters in 1 byte each and Devanagari in 3 Grade 7: Unicode: every script in the world. Now you can see how.

Code points in hex

Unicode’s own charts write code points in hex, after U+: A is U+0041 (65), न is U+0928 (2344), 😀 is U+1F600. Hex is used because the charts are laid out in columns of sixteen: the last hex digit gives the place in the column, and the digits before it name the column. The Devanagari block runs from U+0900 to U+097F: 128 codes, eight columns of sixteen. So a hex code point shows at a glance which script a character belongs to: every code from U+0900 to U+097F is Devanagari (Bengali comes next, from U+0980).

Try it

Code points as Unicode writes them

Type or pick some text. Each box shows a character and its code point, written the way Unicode’s charts write it. Which hex digits do all the Devanagari ones share?

न U+0928 ◌े U+0947 प U+092A ◌ा U+093E ल U+0932
Characters (numbers stored)
5

Type something, or pick one of the buttons.

Every English letter, digit, space and punctuation mark has its own number. A capital and a small letter have different numbers.

Every character, of every script, is stored as its own number.

A Nepali syllable is stored as several numbers: a letter, then its vowel sign or a halant (्) and the next letter.

Each English character is a number under 128, so it fits in one byte.

English characters take 1 byte each, but every Devanagari letter or sign takes 3 bytes: its number is over 2,047.

An emoji’s number is over 65,535, so it takes 4 bytes. Nepali letters take 3, English ones 1.

The bigger a character’s number, the more bytes it takes: 1, 2, 3 or 4.

Answer

How UTF-8 packs a code point into bytes

UTF-8 has to solve a puzzle. A code point can be anything from 0 to U+10FFFF (1,114,111), so some need 1 byte and some need 4. But when a phone reads a stream of bytes, how does it know where one character ends and the next begins?

The answer is in the first few bits of every byte:

Code point Bytes The bytes’ bits (x = the code point’s own bits)
U+0000 to U+007F (ASCII) 1 0xxxxxxx
U+0080 to U+07FF 2 110xxxxx 10xxxxxx
U+0800 to U+FFFF (Devanagari here) 3 1110xxxx 10xxxxxx 10xxxxxx
U+10000 to U+10FFFF (most emoji) 4 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
  • A byte starting 0 is a whole character by itself: plain ASCII, so an English file in ASCII is already UTF-8.
  • A byte starting 110, 1110 or 11110 starts a character, and its number of 1s says how many bytes the character has: two, three or four.
  • A byte starting 10 is a continuation: it carries six more bits of the character already begun.

So the code point’s bits are cut into pieces and poured into the x’s, as Figure 2.1 shows for न.

नU+0928its code point in 16 bits000010010010100011100000E01 byte: starts a 3-byte character10100100A41 byte: continues it10101000A81 byte: continues itcut into piecesof 4, 6 and 6 bitsgray bits:UTF-8’s markersनU+0928its code point in 16 bits000010010010100011100000= E01 byte: starts a 3-byte character10100100= A41 byte: continues it10101000= A81 byte: continues itcut into pieces of 4, 6 and 6 bits,each put after its byte’s gray marker bits:
Figure 2.1 How UTF-8 stores न, code point U+0928. Its 16 bits are cut into pieces of 4, 6 and 6 and placed after the marker bits 1110, 10 and 10, making three bytes: E0 A4 A8 in hex.

Python can show you the bytes. encode("utf-8") turns text into its bytes, and len() counts them:

word = "नमस्ते"print(len(word), "code points")print(len(word.encode("utf-8")), "bytes")print("न".encode("utf-8"))

Output

6 code points18 bytesb'\xe0\xa4\xa8'

b'\xe0\xa4\xa8' is Python’s way of writing three bytes: \x and then each byte in hex, E0, A4 and A8, exactly as in Figure 2.1.

One letter, many bytes

What you see as one Nepali letter is often several code points (Grade 7: क्ष is क, the halant ◌्, ष). Each Devanagari code point takes 3 bytes, so a single syllable such as क्षि is 4 code points, क ◌् ष ◌ि, and 12 bytes.

Try it

Count the bytes

Each box is a code point, and the small squares under it are its bytes. Compare क्षि with ki, and Nepal with नेपाल.

क U+0915 ◌् U+094D ष U+0937 ◌ि U+093F
Characters (numbers stored)
4
Bytes in UTF-8
12

Type something, or pick one of the buttons.

Every English letter, digit, space and punctuation mark has its own number. A capital and a small letter have different numbers.

Every character, of every script, is stored as its own number.

A Nepali syllable is stored as several numbers: a letter, then its vowel sign or a halant (्) and the next letter.

Each English character is a number under 128, so it fits in one byte.

English characters take 1 byte each, but every Devanagari letter or sign takes 3 bytes: its number is over 2,047.

An emoji’s number is over 65,535, so it takes 4 bytes. Nepali letters take 3, English ones 1.

The bigger a character’s number, the more bytes it takes: 1, 2, 3 or 4.

Answer

A text holds the word ज्ञान (ज ◌् ञ ◌ा न). How many bytes does it take in UTF-8?

Pick an answer to see why.

How big is a file?

Pictures

In Grade 7 each pixel took 3 bytes, one each for red, green and blue. That is not the only choice. The number of bits used for each pixel is called the color depth (or bit depth), and it decides how many colors the picture can have:

Color depth Colors Used for
1 bit 2 black and white, like Grade 6’s pictures and a QR code
8 bits 2⁸ = 256 simple pictures with few colors, such as a logo
24 bits 2²⁴ = 16,777,216 photos: 8 bits each for red, green and blue

The size of the pixels, before any compression, is

size in bits=width×height×color depth \text{size in bits} = \text{width} \times \text{height} \times \text{color depth}

Then divide by 8 for bytes, and by 1,024 for each step to KB and MB.

Sound

Sound is stored as samples (Grade 7), so its size depends on four things: how many samples a second (the sample rate), how many bits each sample takes (the bit depth), how many channels (1 for mono, 2 for stereo: left and right), and how long it lasts.

size in bits=sample rate×bit depth×channels×seconds \text{size in bits} = \text{sample rate} \times \text{bit depth} \times \text{channels} \times \text{seconds}

Try it

What sound costs

Choose the samples a second and the bits a sample, and watch both the stored wave and the bytes a second it costs, for stereo. Which setting costs the most? Which halves the size?

04 thousandths of a second
Samples a second:
Bits a sample:
Levels
65,536
Bytes for 1 second, stereo
176,400
For 1 minute
10.1 MB

Only a few samples: the dots miss the wave’s wiggles, so the stored sound is rough.

Few bits, few levels: each sample is rounded to the nearest level, so the steps jump.

More samples and more levels: the steps follow the wave more closely, but each second takes more bytes.

44,100 samples a second, 16 bits each: at least as good as a music CD. The steps are far too small to see or hear.

44,100 samples a second, 16 bits each, as on a music CD: the steps are too small to see or hear.

What you should see

A real file is a little bigger than these sums, because it also holds a header and metadata: the picture’s width and height or the sound’s sample rate, so it can be read back, and often a date, a place, a camera’s name or a song’s title Grade 8: Metadata: data about data. These are usually only a few kilobytes.

A picture is 100 × 100 pixels with a color depth of 1 bit. How many bytes?

Pick an answer to see why.

Compression

So a song is about 40 MB uncompressed, and a phone photo about 34 MB. Yet the files on a phone are about 4 MB and 3 MB. They have been compressed: stored in fewer bits by a program that finds a shorter way to say the same thing. Compressing a file makes it quicker to send, cheaper on a data pack, and lets a phone hold ten times as many.

How much smaller a file gets is its compression ratio: the original size ÷ the compressed size. A 40 MB song stored in 4 MB has been compressed 10 times, a ratio of 10 : 1.

As Grade 8 said Grade 8: Choosing a format, there are two families:

  • Lossless compression keeps every bit. Decompress the file, and you get back exactly the original.
  • Lossy compression throws away detail that people won’t notice, so it can squeeze far more, but the lost detail is gone for good.

Lossless: repeated runs

Look at the sky in a photo of the Himalaya: hundreds of pixels side by side, all the same blue. Listing “blue, blue, blue, blue…” wastes space. Better to say “200 × blue”. This is run-length encoding (RLE): each run of the same value is stored as a count and the value once.

Try it

Count the runs

Each row of this picture is stored as runs: a count and a color, 1 byte each. Each pixel uncompressed is 1 byte. Tap a row’s number to see it as runs. Paint pixels (choose a color, then tap or drag), or pick another picture, and watch the size. Which picture gets smaller, and which gets bigger?

Row 5 stored as runs:
3382
Paint:
Uncompressed
160 bytes
Runs
36 × 2 = 72 bytes
Compressed size
45% of the original

Long runs of one color are stored as just two bytes each, so the picture shrinks.

The runs take exactly as many bytes as the pixels: nothing is saved.

The runs are so short that storing a count with every color takes more bytes than the pixels themselves.

What you should see

RLE is simple, and it shows the big truth about every lossless method: it works by finding a pattern. Where there is no pattern, there is nothing to squeeze. Here is RLE in Python: change the text and run it.

text = "WWWWWWBBBWWWW"encoded = ""count = 1for i in range(1, len(text) + 1):    if i < len(text) and text[i] == text[i - 1]:        count = count + 1    else:        encoded = encoded + str(count) + text[i - 1] + " "        count = 1print(encoded)

Output

6W 3B 4W

text[i] is the character at position i (you will do much more with text in Unit 3). The loop compares each character with the one before it: while they match, the count goes up; when they differ, or the text ends, the run is written out and a new count starts.

Lossless: repeats anywhere (the idea inside ZIP)

Runs are only one kind of pattern. Text is full of others: a word or a phrase that came before, coming again. The ZIP files you download, and the PNG pictures of Grade 8, both use a cleverer idea: whenever a piece has appeared before, store a pointer back to it instead: “go back 34 characters and copy 18”.

Try it

Pointers back to earlier text

Each blue chip is a pointer: go back so many characters, copy so many. Here a pointer is counted as taking the space of 2 characters. Tap a chip to see the earlier text it copies. Try the other texts, then type your own. Which one hardly shrinks at all?

The text
Class 9A: Science test on Sunday. Class 9B: Science test on Monday. Class 9C: Science test on Sunday. Bring a pencil.
Stored as
Class 9A: Science test on Sunday. BMoCBring a pil.
Text
117 characters
Stored
50 + 5 × 2 = 60
Size
51% of the text

↶68,26: go back 68 characters and copy 26. The text underlined in blue is copied to the place shaded yellow.

No piece of 3 or more characters comes twice, so there is nothing to point back to, and nothing is saved.

What you should see

ZIP and PNG then take a second step: letters and pointers that come up often get shorter codes, and rare ones longer codes. Morse code works the same way: E, the most common letter in English, is a single dot, and a rare Q is four signals. Together the two steps often shrink a text file to a third of its size or less, and get back every character exactly.

Lossy: what the eye misses (JPEG)

A photo has a different problem. Its pixels are almost never exactly the same: the sky changes color very slightly from pixel to pixel, so lossless methods find few runs or repeats, and a PNG of a photo stays big. So JPEG, which you met in Grade 8 Grade 8: Pixels and kilobytes, uses what is known about eyes:

  1. Color is kept with less detail than brightness. Your eyes see fine detail in light and dark much better than in color. So a JPEG usually keeps the brightness of every pixel, but only one color for each 2 × 2 square of four pixels.
  2. The picture is cut into blocks of 8 × 8 pixels, and each block is described as a mix of smooth patterns, from a plain block to fine stripes (the discrete cosine transform of Grade 8’s fact).
  3. The finest patterns are thrown away or kept only roughly, because eyes hardly notice them. The quality setting decides how much: lower quality, rougher patterns, smaller file.
  4. What is left is squeezed losslessly, with Huffman’s codes.

Push the quality too low, and the 8 × 8 blocks start to show, and smudges appear round sharp edges: the compression artifacts of Grade 8.

Try it

Throwing detail away

The browser saves this photo as a real JPEG as you change the quality, and shows the real file size. Watch the close-up as you lower the quality: when can you first see the 8 × 8 blocks? Compare the PNG, which keeps every pixel.

Loading the photo…

Close-up of the red box: the saved file’s own pixels, 2.6 times bigger
Format:
Width:
Size in pixels
800 × 533
Raw (× 3 bytes a pixel)
1.2 MB
The saved file
…

The browser is saving the photo as a file…

PNG keeps every pixel exactly, so a photo’s file is huge. PNG is for screenshots and drawings; for a photo, choose JPEG or WebP.

It fits, and the close-up still looks clean. This is the way: fewer pixels first, then the quality only as low as it must go.

It fits, but look at the close-up: at this quality, blocks and smudges appear round the sharp edges. Try a smaller width and a higher quality.

Too big for the form. Make it narrower first: half the width is a quarter of the pixels. Then lower the quality a little.

Photo: Vyacheslav Argenberg, CC BY 4.0, via Wikimedia Commons

Lossy: what the ear misses (MP3)

MP3 does the same for sound, using what is known about ears:

  • Sounds too high or too quiet to hear are dropped. People hear from about 20 to 20,000 vibrations a second, and quiet sounds only in the middle of that range.
  • Loud sounds hide quiet ones near them in pitch. Next to a loud drum beat, a quiet note just a little higher can’t be heard at all; for a short moment after the beat, nothing quiet is heard either. This is called masking, and it is the biggest trick: whatever is masked isn’t stored.
020406080201001,00010,000pitch: vibrations a second (Hz)loudness (dB)loud tone: keptquiet tone hidden bythe loud one: not storedquiet tone heard: kepttoo quiet to hear:not storedcan’t be heard020406080201001,00010,000pitch (Hz)loudness (dB)loud tone: kepthidden by theloud tone:not storedheard: kepttoo quiet tohear: not stored
Figure 2.2 A simplified picture of what an MP3 encoder works out for one short moment of sound. Below the dashed line nothing can be heard. A loud tone (red) raises the line near its own pitch, so the quiet tone beside it is hidden and need not be stored. The quiet tone at a higher pitch rises above the line, so it is heard and kept.

Masking is what Karlheinz Brandenburg’s team was tuning when they played Suzanne Vega’s Tom’s Diner over and over, in Grade 8’s story Grade 8: Recording clean sound: a voice alone has nothing loud beside it to hide the encoder’s mistakes.

An MP3 is described by its bit rate: how many bits it stores for each second of sound, for example 128 kbps, 128 kilobits a second. Now the opening question has its answer:

Lossless or lossy?

Choose by asking one question: would a tiny change matter?

  • Text, numbers, programs, spreadsheets and ZIP files must be lossless. Change one bit in a bank’s file, and Rs 1,000 could become Rs 9,000; change one bit in a program, and it may not run.
  • Photos, music and video for people to look at and listen to can be lossy: they have far more detail than eyes and ears take in.
  • Some pictures must stay exact even so: a screenshot with small writing, a diagram with sharp lines, an X-ray a doctor must read, a photo you are still editing. Keep those lossless.

Try it

Lossless or lossy?

For each file, choose how you would compress it.

a song to keep on your phone

Would you compress it lossless or lossy?

Tap a group above.

Card
1 of 10
Right the first time
0

In short

Exercise

What is the base of the octal number system?

Pick an answer to see why.

In the hexadecimal system, what does the symbol D stand for?

Pick an answer to see why.

What is (1110)₂ + (1011)₂?

Pick an answer to see why.

What is the binary equivalent of (53)₈?

Pick an answer to see why.

Which 8-bit two’s complement number is −2?

Pick an answer to see why.

Which file should not be saved with lossy compression?

Pick an answer to see why.

a.

Answer these questions.

  • i.What is a number system?
  • ii.Define the base or radix of a number system.
  • iii.Name four number systems, with the base and the digits of each.
  • iv.What is the hexadecimal number system? Write the symbols it uses.
Answer
b.

Perform these binary additions.

  • i.(11110)₂ + (1001)₂
  • ii.(1010)₂ + (110)₂
  • iii.(100111)₂ + (11010)₂
  • iv.(110001)₂ + (100101)₂
Answer
c.

Perform these binary subtractions and multiplications.

  • i.(1100)₂ − (1001)₂
  • ii.(11101)₂ − (1010)₂
  • iii.(101100)₂ − (10011)₂
  • iv.(1000001)₂ − (10101)₂
  • v.(110)₂ × (11)₂
  • vi.(1011)₂ × (101)₂
Answer
d.

Convert these decimal numbers to binary: i. (56)₁₀ ii. (123)₁₀ iii. (540)₁₀

Answer
e.

Convert to decimal: i. (11100111)₂ ii. (763)₈ iii. (B74)₁₆ iv. (DEF)₁₆

Answer
f.

Convert: i. (216)₁₀ to octal ii. (1334)₁₀ to octal iii. (225)₁₀ to hexadecimal iv. (2046)₁₀ to hexadecimal

Answer
g.

Convert: i. (11110000111)₂ to hexadecimal ii. (1110010110)₂ to hexadecimal iii. (FACE)₁₆ to binary iv. (A9F)₁₆ to binary

Answer
h.

Why do computer people use hexadecimal? Give two reasons, and two places where hex numbers are seen.

Answer
i.
  • i.Write −20 in 8-bit two’s complement, showing your steps.
  • ii.What number does the 8-bit two’s complement 10011100 stand for?
  • iii.Work out 50 − 20 by adding 50 and −20 in 8-bit two’s complement.
Answer
j.

Explain why the one Nepali syllable स्त्री takes 18 bytes in UTF-8, while the English word stree takes 5.

Answer
k.

A photo is 4,000 × 3,000 pixels with a color depth of 24 bits.

  • i.How big are its pixels, in MB, uncompressed?
  • ii.Saved as a JPEG it is 3 MB. What is the compression ratio?
  • iii.Name two things JPEG throws away, and say why you don’t notice.
Answer
l.

A school records its morning assembly: 22,050 samples a second, 16 bits a sample, mono, for 10 minutes.

  • i.How big is the recording uncompressed, in MB?
  • ii.Saved as an MP3 at 64 kbps, how big is it?
Answer
m.

Encode each row with run-length encoding, and say whether it got smaller. Count each pixel as 1 byte, and each run as 2 bytes (a count and a color).

  • i.RRRRRRRRGGGGBBBBBBBB
  • ii.RGRGRGRGRG
Answer
n.

What is the difference between lossless and lossy compression? Which would you use for each of these, and why? i. a Python program ii. a song for your phone iii. a screenshot of a bank statement iv. a photo for a school’s social media page

Answer
o.

A file holds the 16 letters ABABABABABABABAB.

  • i.Encode it by run-length encoding (a count and a letter for each run, 2 bytes a run). Does it get smaller?
  • ii.Store it with pointers back to earlier text instead. What is stored?
  • iii.What does this tell you about how compression methods find patterns?
Hint
Answer