Числа с плавающей запятой в Python: типы данных и практические примеры

Раздел: Основы Python -> Типы данных

Числа с плавающей запятой в Python: основные принципы и нюансы

Числа с плавающей запятой (float) - один из базовых типов данных в Python, предназначенный для представления вещественных чисел. Они реализованы на основе стандарта IEEE 754 и обладают ограниченной точностью, что может приводить к неожиданным ошибкам при вычислениях. В этой статье разбираются основные способы работы с float и альтернативные подходы для ситуаций, требующих повышенной точности.

Основной способ: создание и арифметика с float

Как создать число с плавающей запятой и выполнить базовые операции?

Самый простой способ - записать число с десятичной точкой или использовать функцию float().

a = 3.14
b = float("2.718")
c = 1e-3   # научная нотация
print(a, b, c)
# Результат: 3.14 2.718 0.001

Set str python (множество из строки в python)

Арифметические операции работают как обычно:

x = 0.1 + 0.2
print(x)  # Результат: 0.30000000000000004

Python переменная время (переменные для времени в python)

Проблема:

Из-за двоичного представления числа 0.1 и 0.2 не могут быть точно сохранены, поэтому результат сложения содержит погрешность. Это типичная ошибка при сравнении: 0.1 + 0.2 == 0.3 вернёт False.

Решение: использовать округление, сравнение с допуском или более точный тип Decimal.

Для приведения целых чисел к float используется float():

n = 5
print(float(n))  # 5.0

Python объект тип (тип объекта в python)

Обратное преобразование int() отбрасывает дробную часть (не округляет):

print(int(3.9))   # 3
print(int(-3.9))  # -3

вещественные значения python (вещественные значения в python)

Вариант 1: Decimal - точные десятичные вычисления

Как выполнять точные финансовые расчёты без погрешностей двоичной арифметики?

Модуль decimal предоставляет десятичный тип с настраиваемой точностью. Идеален для денежных операций и ситуаций, где важна десятичная точность.

from decimal import Decimal, getcontext
getcontext().prec = 28  # точность по умолчанию

d1 = Decimal('0.1')
d2 = Decimal('0.2')
print(d1 + d2)  # 0.3

вывести тип данных python (вывод типа данных в python)

Проблемы:

  • Производительность ниже, чем у float.
  • Необходимо передавать числа строками или целыми, чтобы избежать неявного преобразования float.

Можно задать округление:

from decimal import ROUND_HALF_UP
price = Decimal('19.995').quantize(Decimal('0.01'), rounding=ROUND_HALF_UP)
print(price)  # 20.00

Python двоичные данные (работа с двоичными данными в python)

Вариант 2: Fraction - рациональные числа

Как представлять числа в виде дробей, чтобы избежать ошибок округления при делении?

Модуль fractions позволяет работать с рациональными числами точно.

from fractions import Fraction
f1 = Fraction(1, 3)
f2 = Fraction(2, 5)
print(f1 + f2)  # 11/15
print(float(f1))  # 0.3333333333333333 (при преобразовании появляется погрешность)

переменная int python какая переменная (переменная int в python - что это?)

Проблема:

При преобразовании Fraction обратно в float точность теряется. Использовать Fraction следует, если все расчёты остаются рациональными.

Вариант 3: Округление чисел

Как округлить float до заданного числа знаков после запятой?

Функция round(), форматирование строк и методы math.floor/math.ceil.

x = 2.675
print(round(x, 2))  # 2.67 (банковское округление: к чётному)

# Форматирование
print(f"{x:.2f}")   # 2.67
print("{:.2f}".format(x))  # 2.67

# Математические функции
import math
print(math.floor(2.7))  # 2
print(math.ceil(2.1))   # 3

логические значения python (логические значения в python)

Типичная ошибка:

round() может давать неожиданные результаты из-за двоичного представления: round(2.675, 2) даёт 2.67, а не 2.68. Для строгого правильного округления используйте Decimal с ROUND_HALF_UP.

Вариант 4: Сравнение чисел с допуском

Как корректно проверить равенство двух float?

Вместо == используется сравнение разности с маленьким epsilon.

a = 0.1 + 0.2
b = 0.3
e = 1e-9
print(abs(a - b) < e)  # True

длина переменной python (длина числа и переменной в python)

Проблема:

Выбор epsilon - нетривиальная задача. Слишком маленький - возможен false negative, слишком большой - false positive. Лучше использовать math.isclose.

Вариант 5: math.isclose - стандартный способ сравнения

Как проверить, что два float приблизительно равны, с учётом масштаба чисел?

import math
print(math.isclose(0.1 + 0.2, 0.3))  # True, по умолчанию rel_tol=1e-9, abs_tol=0.0
print(math.isclose(1000000000.1, 1000000000.2, rel_tol=1e-10))  # False, потому что разница велика относительно масштаба

определение объекта python (определение типа объекта в python)

Можно задать абсолютный допуск:

print(math.isclose(0.000001, 0.000003, abs_tol=1e-5))  # True
- List values python (список значений словаря в python)
- числа с плавающей запятой python (числа с плавающей запятой в python)
- является ли числом python (проверка, является ли значение числом в python)

Расширенные примеры работы с числами с плавающей запятой

Пример 1: Проблема точности на практике

Пример
# Демонстрация накопления ошибки
s = 0.0
for i in range(10):
    s += 0.1
print(s)           # 0.9999999999999999
print(s == 1.0)    # False
0.9999999999999999
False

Пример 2: Использование Decimal для точного суммирования

Пример
from decimal import Decimal, getcontext
getcontext().prec = 30
s = Decimal('0.0')
for i in range(10):
    s += Decimal('0.1')
print(s)           # 1.0
print(s == Decimal('1.0'))  # True
1.0
True

Пример 3: Fraction для рациональных вычислений

Пример
from fractions import Fraction
# Вычисление суммы 1/3 + 1/6
f1 = Fraction(1, 3)
f2 = Fraction(1, 6)
print(f1 + f2)          # 1/2
print(float(f1 + f2))   # 0.5
1/2
0.5

Пример 4: Форматирование с фиксированным числом знаков

Пример
value = 1234.56789
print(f"{value:12.3f}")     # 1234.568
print(f"{value:012.3f}")   # 0001234.568
print(f"{value:.2e}")      # 1.23e+03
    1234.568
0001234.568
1.23e+03

Пример 5: Округление с Decimal и разными режимами

Пример
from decimal import Decimal, ROUND_HALF_UP, ROUND_DOWN, ROUND_CEILING
d = Decimal('2.675')
print(d.quantize(Decimal('0.01'), rounding=ROUND_HALF_UP))   # 2.68
print(d.quantize(Decimal('0.01'), rounding=ROUND_DOWN))      # 2.67
print(d.quantize(Decimal('0.01'), rounding=ROUND_CEILING))   # 2.68 (вверх)
2.68
2.67
2.68

Пример 6: math.isclose с разными tolerances

Пример
import math
# Сравнение больших чисел с относительным допуском
x = 1e10
print(math.isclose(x, x + 1, rel_tol=1e-9))   # True (разница 1 на 1e10)
print(math.isclose(x, x + 1, rel_tol=1e-11))  # False

# Абсолютный допуск для малых чисел
y = 0.0001
z = 0.00011
print(math.isclose(y, z, abs_tol=1e-5))        # True
print(math.isclose(y, z, abs_tol=1e-6))        # False
True
False
True
False

Пример 7: Бесконечность и NaN

Пример
import math
inf = float('inf')
nan = float('nan')
print(inf * 2)          # inf
print(inf - inf)        # nan
print(math.isnan(nan))  # True
print(math.isfinite(inf)) # False
inf
nan
True
False

Пример 8: Преобразование float в двоичное представление (для понимания)

Пример
import struct
def float_to_bin(f):
    return ''.join(f'{b:08b}' for b in struct.pack('!d', f))

print(float_to_bin(0.1))
# Частичная распечатка знака, экспоненты, мантиссы
0011111110111001100110011001100110011001100110011001100110011010

Числа с плавающей запятой в Python - comments

En
числа с плавающей запятой python (python)