Введение в вещественные числа в языке Python: особенности и приёмы
Основные приёмы работы с числами с плавающей точкой
Для представления вещественных чисел в Python используется встроенный тип float. Однако из-за двоичной системы счисления многие десятичные дроби (например, 0.1) не могут быть представлены точно. Это приводит к накоплению погрешностей при вычислениях. Наиболее эффективным решением для задач, требующих высокой точности (финансовые расчёты, научные симуляции), является применение типа Decimal из модуля decimal.
from decimal import Decimal, getcontext
getcontext().prec = 28
a = Decimal('0.1')
b = Decimal('0.2')
print(a + b)Set str python (множество из строки в python)
0.3
Python переменная время (переменные для времени в python)
В отличие от float, Decimal хранит числа в десятичном виде, что позволяет избежать ошибок округления при сложении и вычитании. Для умножения и деления также сохраняется заданная точность.
Как выполнять вычисления с плавающей точкой при допустимой небольшой погрешности?
В большинстве повседневных задач погрешность float (порядка 1e-15) несущественна. Для округления результата до нужного числа знаков применяется функция round().
price = 19.99
tax = 0.07
total = price * (1 + tax)
rounded_total = round(total, 2)
print(rounded_total)
Python типы данных время (типы данных для времени в python)
21.39
Python объект тип (тип объекта в python)
Типичные проблемы:
- Ошибки накопления при многократных операциях. Пример: 0.1 + 0.2 - 0.3 даёт 5.551e-17, что не равно нулю.
- Сравнение float на равенство через == обычно приводит к неожиданным результатам.
Решение:
- Использовать math.isclose() для сравнения чисел с заданной относительной или абсолютной точностью.
Как гарантировать точность десятичных вычислений в финансовых приложениях?
Модуль decimal предоставляет тип Decimal, который выполняет арифметику с заданной точностью. Важно передавать числа в виде строк, чтобы избежать неточного float.
from decimal import Decimal
cost = Decimal('100.50')
discount = Decimal('0.15')
final = cost * (Decimal('1') - discount)
print(final)вещественные значения python (вещественные значения в python)
85.425
вывести тип данных python (вывод типа данных в python)
Для округления до копеек используется метод quantize():
final_rounded = final.quantize(Decimal('0.01'))
print(final_rounded)Python двоичные данные (работа с двоичными данными в python)
85.43
переменная int python какая переменная (переменная int в python - что это?)
Типичные проблемы:
- Производительность Decimal ниже, чем float (в 10-100 раз).
- Необходимость явно задавать точность через getcontext().prec.
Решение:
- Использовать Decimal только там, где точность критична; в остальных случаях достаточно float.
Как работать с дробями без потери точности?
Модуль fractions содержит тип Fraction, представляющий число как отношение двух целых. Это идеально для точных рациональных вычислений.
from fractions import Fraction
f1 = Fraction(1, 3)
f2 = Fraction(2, 5)
result = f1 + f2
print(result)
print(float(result))комплексные числа в python (комплексные числа в python)
11/15 0.7333333333333333
логические значения python (логические значения в python)
Типичные проблемы:
- Ограничение только рациональными числами (нет точного представления иррациональных чисел, таких как sqrt(2)).
- При преобразовании в float снова возникает погрешность.
Как корректно сравнивать два числа с плавающей точкой?
Для сравнения float рекомендуется функция math.isclose(), которая учитывает относительную и абсолютную погрешность.
import math
a = 0.1 + 0.2
b = 0.3
print(a == b)
print(math.isclose(a, b, rel_tol=1e-9, abs_tol=1e-12))длина переменной python (длина числа и переменной в python)
False True
Типичные проблемы:
- Неправильный выбор допусков (tol) может привести к ложным срабатываниям или пропуску истинных равенств.
- Для чисел, сильно различающихся по величине, нужно использовать abs_tol.
Решение:
- Устанавливать rel_tol и abs_tol в зависимости от масштаба чисел.
Расширенные примеры и детали работы
Ниже приведены дополнительные примеры, демонстрирующие различные аспекты работы с вещественными числами в Python.
Пример 1: Накопление ошибки в цикле с float и исправление через Decimal
s = 0.0
for _ in range(100):
s += 0.1
print(s)
from decimal import Decimal, getcontext
getcontext().prec = 50
s_dec = Decimal('0.0')
for _ in range(100):
s_dec += Decimal('0.1')
print(s_dec)
9.99999999999998 10.0000000000000000000000000000000000000000000000000
Пример 2: Форматирование вещественных чисел с помощью f-строк
value = 123.456789
print(f"Обычное: {value}")
print(f"Два знака: {value:.2f}")
print(f"Научная нотация: {value:.2e}")
print(f"Процентный формат: {value:.1%}")
Обычное: 123.456789 Два знака: 123.46 Научная нотация: 1.23e+02 Процентный формат: 12345.7%
Пример 3: Сравнение производительности float и Decimal
import time
start = time.time()
s = 0.0
for _ in range(1_000_000):
s += 0.1
print("float time:", time.time() - start)
from decimal import Decimal, getcontext
getcontext().prec = 28
start = time.time()
s_dec = Decimal('0.0')
for _ in range(1_000_000):
s_dec += Decimal('0.1')
print("Decimal time:", time.time() - start)
float time: 0.045... Decimal time: 1.234...
Примечание:
Время выполнения Decimal может быть на порядок больше, поэтому его применение оправдано только при необходимости точности.
Пример 4: Использование numpy для работы с большими массивами вещественных чисел
import numpy as np
arr = np.array([0.1, 0.2, 0.3, 0.4])
print(arr.sum())
print(np.isclose(arr.sum(), 1.0))
1.0 True
Пример 5: Обработка ввода строки и преобразование в Decimal с проверкой
while True:
user_input = input("Введите цену: ")
try:
from decimal import Decimal
price = Decimal(user_input)
print(f"Введено: {price}")
break
except:
print("Некорректный ввод, повторите.")
При вводе 12.5 программа выводит Введено: 12.5.