Python 2 float: особенности и примеры
Основные аспекты работы с float в Python 2
Наиболее эффективное решение: использование from __future__ import division
В Python 2 оператор / по умолчанию выполняет целочисленное деление для целых операндов. Чтобы получить деление с плавающей точкой (как в Python 3), следует импортировать модуль __future__:
from __future__ import division
result = 5 / 2
print(result) # 2.5Python 2 float (float в python 2)
Этот метод гарантирует единообразное поведение деления во всём файле и является предпочтительным для нового кода, работающего с Python 2.
Как преобразовать целое число в число с плавающей точкой?
Используйте функцию float():
a = 3
b = float(a)
print(b) # 3.0преобразовать в float python (преобразование в float в python)
Этот способ явно приводит тип и помогает избежать неожиданного целочисленного деления.
Типичная ошибка:
При делении двух целых чисел без __future__ результат будет целым:
print(5 / 2) # 2, а не 2.5
Решение: использовать float(5) / 2 или импорт из будущего.
Как округлить число с плавающей точкой до заданного количества знаков?
В Python 2 функция round() работает с числами:
print(round(3.14159, 2)) # 3.14
Однако стоит помнить, что round использует банковское округление (до ближайшего чётного) при равной удалённости.
Проблема:
Функция round возвращает float, что может привести к потере точности при последующих операциях. Для финансовых расчётов лучше использовать модуль decimal.
Как сравнить два float на равенство с учётом погрешности?
Вариант 1: использовать малую постоянную epsilon
a = 0.1 + 0.2
b = 0.3
e = 1e-9
if abs(a - b) < e:
print("Равны в пределах погрешности")
Вариант 2: функция math.isclose (доступна с Python 2.7)
import math
print(math.isclose(0.1 + 0.2, 0.3, rel_tol=1e-9)) # True
Типичная ошибка:
Прямое сравнение 0.1 + 0.2 == 0.3 даёт False из-за двоичного представления.
Как избежать ошибок точности при работе с деньгами?
Используйте модуль decimal:
from decimal import Decimal, getcontext
getcontext().prec = 28
price = Decimal('19.99')
tax = Decimal('0.07')
total = price + price * tax
print(total) # 21.3893
Decimal хранит числа в десятичной форме, что исключает ошибки двоичного представления
Внимание:
Не инициализируйте Decimal из float – это может внести уже существующую погрешность.
Как форматировать вывод чисел с плавающей точкой?
Python 2 поддерживает %-форматирование и метод .format():
value = 123.456789
print("%.2f" % value) # 123.46
print("{:.2f}".format(value)) # 123.46
Для научной нотации используйте %e или :.2e.
Как обрабатывать бесконечность и NaN?
В Python 2 float поддерживает специальные значения:
inf = float('inf')
ninf = float('-inf')
nan = float('nan')
print(inf > 1000) # True
print(inf + inf) # inf
print(inf - inf) # nan
print(nan == nan) # False – NaN не равен самому себе!
Ошибка:
Проверка на NaN должна выполняться через math.isnan(nan), а не через равенство.
Как получить строковое представление float без лишних знаков?
Функция repr() в Python 2.7 возвращает 17 значащих цифр, а str() – 12:
x = 1.0 / 3.0
print(repr(x)) # 0.3333333333333333
print(str(x)) # 0.333333333333
Для точного вывода используйте форматирование.
Расширенные примеры работы с float в Python 2
Пример 1. Поведение деления с и без from __future__ import division
# Без импорта
print(5 / 2) # 2
print(5 // 2) # 2
print(5.0 / 2) # 2.5
# С импортом
from __future__ import division
print(5 / 2) # 2.5
print(5 // 2) # 2 (по-прежнему целочисленное)
Результат: 2 2 2.5 2.5 2
Пример 2. Классическая проблема точности: 0.1 + 0.2
a = 0.1
b = 0.2
print(repr(a + b)) # 0.30000000000000004
print(a + b == 0.3) # False
# Решение с порогом
e = 1e-10
if abs((a+b) - 0.3) < e:
print("Считаем равными")
0.30000000000000004 False Считаем равными
Пример 3. Использование Decimal для точных денежных расчётов
from decimal import Decimal, getcontext
getcontext().prec = 10
price = Decimal('0.10')
count = Decimal('3')
total = price * count
print(total) # 0.30
# Сравнение с float
float_total = 0.1 * 3
print(float_total) # 0.30000000000000004
print(total == Decimal('0.30')) # True
0.30 0.30000000000000004 True
Пример 4. Округление с помощью банковского правила
print(round(2.5)) # 2.0 ( до ближайшего чётного)
print(round(3.5)) # 4.0
print(round(2.675, 2)) # 2.67 (из-за двоичного представления)
2.0 4.0 2.67
Пример 5. Специальные значения: inf, -inf, nan
import math
pos_inf = float('inf')
neg_inf = float('-inf')
not_a_num = float('nan')
print(math.isinf(pos_inf)) # True
print(math.isinf(neg_inf)) # True
print(math.isnan(not_a_num)) # True
# Арифметика с бесконечностями
print(pos_inf + 1000) # inf
print(pos_inf - pos_inf) # nan
True True True inf nan
Пример 6. Преобразование float в int с потерей дробной части
x = 3.99
print(int(x)) # 3 (отбрасывание дробной части)
print(math.floor(x)) # 3.0
print(math.ceil(x)) # 4.0
3 3.0 4.0
Пример 7. Форматирование с научной нотацией
big = 1234567.89
print("%e" % big) # 1.234568e+06
print("{:.3e}".format(big)) # 1.235e+06
1.234568e+06 1.235e+06
Пример 8. Проверка на приблизительное равенство нескольких чисел
import math
values = [0.1 * i for i in range(1, 11)]
target = 1.0
if any(math.isclose(v, target, rel_tol=1e-3) for v in values):
print("Есть значение, близкое к 1.0")
Есть значение, близкое к 1.0