Вопрос проверяет понимание особенностей работы чисел с плавающей точкой и правильных способов их сравнения.
Числа с плавающей точкой нельзя сравнивать напрямую из-за погрешностей представления. Вместо этого сравнивают разницу между числами с заданной точностью. Обычно используют значение допуска, например epsilon. В Python для этого есть функция math.isclose().
Числа с плавающей точкой хранятся в двоичном формате, и многие дроби не могут быть представлены точно. Это приводит к небольшим ошибкам округления.
Пример проблемы:
0.1 + 0.2 == 0.3 # False
Фактический результат отличается на очень маленькую величину.
Определение:
Допуск (tolerance) — это максимально допустимая разница между числами, при которой они считаются равными.
Пример:
abs(a - b) < 1e-9
Такой способ работает в большинстве задач.
Стандартный способ в Python:
import math
math.isclose(a, b, rel_tol=1e-9, abs_tol=1e-12)
Параметры:
rel_tol — относительная погрешность
abs_tol — абсолютная погрешность
Это удобно, когда числа могут иметь разный масштаб.
Основные причины:
Двоичное представление дробей
Округления при операциях
Накопление ошибок при множественных вычислениях
Например, в циклах ошибка может постепенно увеличиваться.
Рекомендуется:
Выбирать допуск исходя из задачи
Не использовать слишком маленький epsilon без необходимости
Учитывать масштаб данных
Если числа порядка 1e6, то допуск должен быть больше, чем для чисел порядка 1.
В PyTest часто используют:
import pytest
def test_value():
assert pytest.approx(0.3, rel=1e-6) == 0.1 + 0.2
Это более надежный способ тестирования числовых функций.
Числа с плавающей точкой нельзя сравнивать напрямую. Надежный подход — использовать допуск или специализированные функции вроде math.isclose или pytest.approx.