Check If the Floating Point Numbers Are Close in Python: math.isclose

Modified: | Tags: Python, Numeric

Floating point numbers, float, are represented in binary inside computers, so they cannot represent exactly the same values as decimal numbers. This can lead to unexpected results when comparing floating point numbers.

See the following article about NumPy functions np.isclose() and np.allclose().

Notes on comparing floating point numbers

Floating point numbers, float, are represented in binary inside computers, so they cannot represent exactly the same values as decimal numbers.

For example, print(0.1) outputs 0.1. This output, however, is an approximation. Python rounds the actual binary representation of 0.1 to a manageable number of decimal places for display. If you increase the number of digits with format(), you may find that it actually contains an error.

print(0.1)
# 0.1

print(format(0.1, '.20f'))
# 0.10000000000000000555

See the official documentation for details.

In many cases, there is no need to be concerned about such errors. However, they can lead to unexpected results, especially when comparing the results of operations with floating point numbers.

print(0.1 + 0.1 + 0.1)
# 0.30000000000000004

print(0.1 + 0.1 + 0.1 == 0.3)
# False
print((19 / 155) * (155 / 19))
# 0.9999999999999999

print((19 / 155) * (155 / 19) == 1)
# False

For example, you can use round() to round, or abs() to compare the absolute value of the difference with a sufficiently small value.

print(round(0.1 + 0.1 + 0.1, 10) == round(0.3, 10))
# True

print(abs((0.1 + 0.1 + 0.1) - 0.3) < 1e-10)
# True

In Python, 1e<number> is a way to express floating point numbers in scientific notation. Here, 1e<number> represents 10 to the power of <number>. It's important to note that the e used here is a symbol for exponentiation, not Euler's number.

print(1e5)
# 100000.0

print(1e-3)
# 0.001

Check if the two floating point numbers are close: math.isclose()

You can write a comparison of floating point numbers like examples above simply by using the function isclose() in the math module.

As shown below, math.isclose(a, b) returns True if a and b are approximately equal.

import math

print(math.isclose(0.1 + 0.1 + 0.1, 0.3))
# True

print(math.isclose((19 / 155) * (155 / 19), 1))
# True

Specify tolerances: rel_tol, abs_tol

You can specify the tolerable difference with the rel_tol and abs_tol arguments. By default, rel_tol is set to 1e-9, and abs_tol is set to 0.0.

rel_tol is the relative tolerance, and it is the maximum allowed difference between two values, relative to the larger absolute value.

abs(a - b) <= rel_tol * max(abs(a), abs(b))
print(math.isclose(1, 1.001))
# False

print(math.isclose(1, 1.001, rel_tol=0.01))
# True

abs_tol is the minimum absolute tolerance.

abs(a - b) <= abs_tol

It is compared to the larger of the relative and absolute tolerances.

abs(a - b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol)

Be careful when comparing a number with 0. For example, if b=0, the comparison math.isclose(a, b) will not return True unless rel_tol=0. This is because the comparison is evaluated as follows:

abs(a) <= rel_tol * abs(a)

Remember to specify abs_tol when needed, as it defaults to 0.0.

print(math.isclose(0, 0.001))
# False

print(math.isclose(0, 0.001, rel_tol=0.01))
# False

print(math.isclose(0, 0.001, abs_tol=0.01))
# True

Compare floating point number with 0

As mentioned above, be careful when comparing the result of a floating point operation to 0. Using == or math.isclose() by default may produce unexpected results.

The same is true for operations dealing with irrational numbers, such as pi.

print(math.sin(math.pi))
# 1.2246467991473532e-16

print(math.sin(math.pi) == 0)
# False

print(math.isclose(math.sin(math.pi), 0))
# False

You can specify abs_tol in math.isclose(), round with round(), or compare with a sufficiently small value instead of 0.

print(math.isclose(math.sin(math.pi), 0, abs_tol=1e-10))
# True

print(round(math.sin(math.pi), 10) == 0)
# True

print(abs(math.sin(math.pi)) < 1e-10)
# True

Related Categories

Related Articles