You are Better at Maths Than a Computer

Ok… this claim is a bit tongue in cheek but let me demonstrate one way of how you are “better at maths” than a computer.

Let’s consider the following piece of code in Python.

What do you expect to be printed (0.1+0.2)?
0.3 right? we know 0.1 + 0.2 = 0.3.
Well………………

The output of this code is 0.30000000000000004

WHAT? HOW?

You might well be thinking “I will never use Python again” but this would happen in nearly all programming languages. Before I explain it lets just bask in the glory that you are better at maths than a computer!

It thinks 0.1 + 0.2 is not 0.3.

Basking in glory…
Basking in glory…
Basking in glory.

WHY?

To illustrate this, we first need to introduce a difference between the way we view numbers vs the way a computer does.

We are taught numbers in the base10 system

So, when we write a number we think in hundreds, 10ths and units. Let’s say we have 3 and a half items – we can write this in base10 as follows.

3 units and 5/10’s
Or 3 and a half
Or in decimal 3.5

Easy right?

But what if we have 3 and a third items?

Its 3.333333333333333333333333333333333333 (repeating 3 until infinity). This is because 10 doesn’t divide by 3 evenly.

So, let’s ask another question?

what is 1/3 + 1/3 + 1/3?
Well… its 3/3 or 1 isn’t it?
Correct!

but what if we ask the same question using decimals and not fractions?

0.3333333… + 0.3333333… + 0.3333333… = 0.9999999…
Answer: 0.999999…
Is this 1? no, not quite.

Now a computer will at some point stop recurring the 9 – it cannot go on until infinity.

This is what we see in our example from the start and is a floating point rounding error but this example is in base10 so it’s easier for us to understand.

Let’s go back and look exactly what the computer is doing in our example (0.1 + 0.2)

Base2 Example

Base2 doesn’t work in 100’s,10’s and units. It in 2’s

If we revisit our 1/10 example in base 10 and base 2.

You can see 0.1 doesn’t fit directly in base2 and the highlighted 0011 is recurring. So, 0.1 in base2 is actually: 0.000110011001100110011001100110011001100110011001100110011001… to infinity.

32 bit computers store 23 significant digits
64 bit computers store 52 significant digits
Eventually the recursion stops as you run out of digits.

So, what is happening in our example?

1/10 + 2/10
In decimal can be written as 0.000110011001100110011… + 0.00110011001100110011……
and at some point, the recursion stops.

Therefore, we reach a point where 0.1 + 0.2 Does not equal 0.3.

How do fix this?

In contemporary programming languages you can use more advance numeric types such as decimals or currencies – we can correct our initial code as follows.

This code would return 0.3

Historically in older systems you could just store the decimals as integers so for example if our 0.1 represents 10p you could store that number as 10.

This code would return 0.3

Conclusion

This is a fun little example showing a problem that I am sure nearly every programmer has had at some point in their career. I also think it’s an interview question that appears from time to time (is 0.3 = 0.1+0.2 True).

Does using a floating decimal like this matter? Well, it depends on what you are doing – if you are a video game programmer and you render a pixel that is out of position by 0.00000000001 pixel – no it does not matter. But what if you are writing financial software, you could store 10p as £0.1 and 20p as £0.2 this would lead over enough transactions to material differences.

I am sure I once read about a skimming fraud at a bank that was undetected because it was assumed rounding errors in the reporting were the cause of the discrepancies.

So, this issue can be serious, it’s important to know of its existence – but more interestingly you can now make a claim that in some way you are better at maths than a computer.