# preface

If you haven’t experienced the so-called floating point error in your code, you’re lucky.

For example, 0.1 + 0.2 does not equal 0.3, and 8.7/10 does not equal 0.87, but 0.869999… It is so strange 🤔

But this is definitely not a netherworld bug, nor is it a problem with Python’s design. It is a natural consequence of the way floating point numbers are computed, so it is the same even in JavaScript or any other language:

# How does a computer store an Integer?

Before we talk about why floating point errors occur, let’s talk about how computers use 0 and 1 to represent integers. We all know binary: 101 represents $2^2 + 2^0$(5), and 1010 represents $2^3 + 2^1$(10).

## Double precision floating-point numbers

In order to minimize the error, IEEE 754 also defines how to use 64 bits to represent a single precision floating point number. Compared with 32 bits, the fraction is more than twice as large, from 23 bits to 52 bits. So the accuracy will naturally improve a lot.

Taking 8.9 as an example, 64 bit representation can be more accurate, but because 8.9 cannot be completely written as the sum of two numbers, there will still be errors under the decimal 16 bits, but it is much smaller than the error of 0.0000003 for a single precision

The same is true of Python 1.0 and 0.999… 999 is the same, 123 is 122.999… 999 is also the same. Since the gap between them is too small to be placed in fraction, each bit of them is the same from the perspective of binary format.

# The solution

Since floating-point errors are unavoidable, you have to live with them. Here are two common ways to deal with them:

## Set the maximum permissible error ε (epsilon)

Some languages provide what’s called epsilon, which lets you determine if you’re within the allowable range of floating point errors. In Python, epsilon is about $2.2e^{-16}$

So you can rewrite 0.1 + 0.2 == 0.3 as 0.1 + 0.2-0.3 <= epsilon, which will avoid the floating point error in the calculation process, and correctly compare whether 0.1 + 0.2 is equal to 0.3.

Of course, you can define your own epsilon if the system doesn’t provide it, and set it to the power of 2 to the minus 15

## Calculate entirely in decimal

The reason for the floating point error is that the process of converting from decimal to binary cannot fit all the decimal parts into the mantissima. Since there may be an error in the conversion, we simply do not convert, and use the decimal system to do the operation.

There’s a module called decimal in Python, and there’s a similar package in JavaScript. It will help you calculate in decimal terms, just as you can calculate 0.1 + 0.2 with pen and paper without any error or error.

Although Decimal calculation can completely avoid floating-point error, since Decimal calculation of DECIMAL is simulated, binary calculation is still carried out in the lowest CPU circuit, which will be much slower than the original floating-point calculation. Therefore, it is not recommended to use DECIMAL for all floating-point calculations.