Все знают, или, по крайней мере, каждый программист должен знать, что использование типа float
может привести к ошибкам точности. Однако в некоторых случаях точное решение было бы замечательным, и бывают случаи, когда сравнивать с использованием значения epsilon недостаточно. Во всяком случае, это не совсем так.
Я знал о типе Decimal
в Python, но никогда не пытался его использовать. В нем указано, что "Десятичные числа могут быть представлены точно" , и я подумал, что это означает умную реализацию, которая позволяет представлять любое действительное число. Моя первая попытка:
>>> from decimal import Decimal
>>> d = Decimal(1) / Decimal(3)
>>> d3 = d * Decimal(3)
>>> d3 < Decimal(1)
True
Довольно разочарованный, я вернулся к документации и продолжал читать:
Контекст арифметики - это спецификация среды, определяющая точность [...]
Хорошо, так что на самом деле есть точность. И классические проблемы могут быть воспроизведены:
>>> dd = d * 10**20
>>> dd
Decimal('33333333333333333333.33333333')
>>> for i in range(10000):
... dd += 1 / Decimal(10**10)
>>> dd
Decimal('33333333333333333333.33333333')
Итак, мой вопрос: есть способ иметь десятичный тип с бесконечной точностью? Если нет, то какой более элегантный способ сравнения двух десятичных чисел (например, d3 < 1 должен возвращать False, если дельта меньше точности).
В настоящее время, когда я занимаюсь только делениями и умножениями, я использую тип Fraction
:
>>> from fractions import Fraction
>>> f = Fraction(1) / Fraction(3)
>>> f
Fraction(1, 3)
>>> f * 3 < 1
False
>>> f * 3 == 1
True
Это лучший подход? Какие могут быть другие варианты?