<MyRusakov.ru />

Создание игр на Unreal Engine 5

Создание игр на Unreal Engine 5

Данный курс научит Вас созданию игр на Unreal Engine 5. Курс состоит из 12 модулей, в которых Вы с нуля освоите этот движок и сможете создавать самые разные игры.

В курсе Вы получите всю необходимую теоретическую часть, а также увидите массу практических примеров. Дополнительно, почти к каждому уроку идут упражнения для закрепления материала.

Помимо самого курса Вас ждёт ещё 8 бесплатных ценных Бонусов: «Chaos Destruction», «Разработка 2D-игры», «Динамическая смена дня и ночи», «Создание динамической погоды», «Создание искусственного интеллекта для NPC», «Создание игры под мобильные устройства», «Создание прототипа RPG с открытым миром» и и весь курс «Создание игр на Unreal Engine 4» (актуальный и в 5-й версии), включающий в себя ещё десятки часов видеоуроков.

Подробнее
Подписка

Подпишитесь на мой канал на YouTube, где я регулярно публикую новые видео.

YouTube Подписаться

Подписавшись по E-mail, Вы будете получать уведомления о новых статьях.

Подписка Подписаться

Добавляйтесь ко мне в друзья ВКонтакте! Отзывы о сайте и обо мне оставляйте в моей группе.

Мой аккаунт Мой аккаунт Моя группа
Опрос

Какая тема Вас интересует больше?

Числа с плавающей точкой в Python: точность, округление и Decimal/Fraction на практике

Числа с плавающей точкой в Python: точность, округление и Decimal/Fraction на практике

Запросы вроде «точность float в Python», «почему 0.1 + 0.2 != 0.3», «округление денег в Python» встречаются у каждого, кто переходит от «игрушечных» примеров к реальным задачам. В этой статье вы получите практическое руководство по числам с плавающей точкой: как избежать ловушек, когда использовать Decimal или Fraction, и какие инструменты помогают писать надёжный код.

Почему 0.1 + 0.2 != 0.3 в Python

Тип float — это двоичная (IEEE 754) аппроксимация десятичных чисел. Не все десятичные дроби можно представить в двоичной системе точно, поэтому возникает небольшая погрешность.

print(0.1 + 0.2)        # 0.30000000000000004
print((0.1 + 0.2) == 0.3)  # False

# Для «красивого» вывода используйте форматирование
x = 0.1 + 0.2
print(format(x, '.17f'))   # 0.30000000000000004
print(f"{x:.2f}")         # 0.30 (лишь формат вывода, не исправление значения)

Важно понимать: форматированный вывод не меняет реального значения, а только отображение. Для корректных сравнений и вычислений нужны правильные инструменты.

Безопасные сравнения: math.isclose

Сравнивать float на полное равенство — анти‑паттерн. Используйте допуски через math.isclose.

import math

x = 0.1 + 0.2
print(math.isclose(x, 0.3))  # True по умолчанию

# Настраиваемые допуски
print(math.isclose(x, 0.3, rel_tol=1e-09, abs_tol=0.0))

# Для значений около нуля учитывайте abs_tol
print(math.isclose(1e-12, 0.0, abs_tol=1e-10))  # True

Рекомендации: для инженерных расчётов задавайте явные rel_tol и abs_tol, для денег переходите на Decimal.

Округление в Python: round и его особенности

Функция round(x, ndigits) применяет «банковское» округление (Banker’s Rounding, половины к чётному). Это может удивить при .5.

print(round(2.5))   # 2 (к чётному)
print(round(3.5))   # 4
print(round(1.25, 1))  # 1.2
print(round(1.35, 1))  # 1.4

Если вам нужно классическое «.5 вверх», используйте Decimal с режимом ROUND_HALF_UP и фиксируйте масштаб с помощью quantize.

Decimal: точные десятичные вычисления для финансов

decimal.Decimal хранит числа в десятичной системе без двоичных артефактов. Главные правила: создавайте Decimal из строк (или целых), настраивайте контекст и явно задавайте масштаб при деньгах.

from decimal import Decimal, getcontext, ROUND_HALF_UP, localcontext

# Никогда не создавайте Decimal из float: Decimal(0.1) наследует погрешность float!
price = Decimal('0.10')
qty = Decimal('3')
subtotal = price * qty  # 0.30 точно
print(subtotal)  # 0.30

# Настройка контекста (общая точность)
getcontext().prec = 28

# Корректное округление денег до 2 знаков «.5 вверх»
amount = Decimal('10.015')
final = amount.quantize(Decimal('0.01'), rounding=ROUND_HALF_UP)
print(final)  # 10.02

# Локальная настройка контекста (например, временное повышение точности)
with localcontext() as ctx:
    ctx.prec = 40
    print((Decimal('1') / Decimal('7')).quantize(Decimal('0.0000000000000000001')))

Практика: храните деньги в базе как Decimal(precision, scale) или как целые копейки (int), а при показе делите и форматируйте. Для финансовых операций не используйте float.

Fraction: точные рациональные дроби

fractions.Fraction представляет число как рациональную дробь p/q без потерь точности. Полезно в задачах, где требуется строгая рациональная арифметика (комбинаторика, музыкальные интервалы, точные преобразования единиц).

from fractions import Fraction

print(Fraction(1, 3) + Fraction(1, 6))  # 1/2

# Из float — не рекомендуется (унаследуете двоичную погрешность)
print(Fraction(0.1))  # 3602879701896397/36028797018963968

# Правильно: из строки или из десятичной дроби с известным знаменателем
print(Fraction('0.1'))     # 1/10
print(Fraction(1, 10))     # 1/10

# Приближение дробью с ограничением знаменателя (полезно для измерений)
x = 3.14159
print(Fraction(x).limit_denominator(1000))  # 355/113

Fraction идеально точен, но может раздуваться по размеру числителя/знаменателя и быть медленнее. Выбирайте осознанно.

Суммирование и минимизация ошибок: fsum

Даже при float можно уменьшить накопление ошибок благодаря math.fsum, который суммирует с повышенной точностью.

import math
vals = [1e16, 1, -1e16]
print(sum(vals))       # 0.0 (потеря единицы)
print(math.fsum(vals)) # 1.0 (корректнее)

Практические мини‑кейсы

1) Денежные расчёты: скидка, НДС, итоги

from decimal import Decimal, ROUND_HALF_UP

price = Decimal('1999.90')
discount = Decimal('0.15')  # 15%
vat = Decimal('0.20')       # 20%

# Цена со скидкой (два знака после запятой)
price_disc = (price * (Decimal('1') - discount)).quantize(Decimal('0.01'), rounding=ROUND_HALF_UP)

# НДС на итоговую цену
vat_amount = (price_disc * vat).quantize(Decimal('0.01'), rounding=ROUND_HALF_UP)

# Итог к оплате
total = (price_disc + vat_amount).quantize(Decimal('0.01'), rounding=ROUND_HALF_UP)

print(price_disc, vat_amount, total)

Здесь мы явно фиксируем масштаб (2 знака) и режим округления «.5 вверх», как это обычно требуется в отчётности и бухгалтерии.

2) Инженерия: сравнение измерений с допусками

import math

expected = 10.0
measured = 9.9994

# Допуски: 0.01 по абсолютной ошибке или 1e-6 по относительной
print(math.isclose(measured, expected, abs_tol=0.01))  # True
print(math.isclose(measured, expected, rel_tol=1e-6))  # False

Подбирайте допуски согласно требованиям предметной области, фиксируйте их в константах и пишите тесты на граничные случаи.

Когда float, когда Decimal, когда Fraction

  • float — графика, статистика, научные расчёты, где допустимы микропогрешности; используйте math.isclose, math.fsum, форматирование при выводе.
  • Decimal — финансы, отчётность, любые операции с фиксированным количеством знаков; создавайте из строк, применяйте quantize и нужный режим округления.
  • Fraction — точная рациональная математика, преобразования единиц, где важна идеальная точность дробей; следите за производительностью и ростом знаменателей.

Частые ошибки и как их избежать

  • Не сравнивайте float на равенство — используйте math.isclose с явными допусками.
  • Не создавайте Decimal из float: используйте строки или целые числа.
  • Для денег задавайте масштаб через quantize(Decimal('0.01')) и подходящий режим округления (ROUND_HALF_UP и др.).
  • Для суммирования больших списков float применяйте math.fsum.
  • Если нужна математическая точность дробей — используйте Fraction и при необходимости limit_denominator.

Дальше по теме

Хотите быстро собрать прочную базу по Python с практикой, проектами и домашними заданиями? Посмотрите программу курса «Программирование на Python с Нуля до Гуру» — отличный путь от основ к уверенной разработке: Посмотреть программу и стартовать сегодня.

Итог: точность float в Python — не баг, а особенность представления чисел. Зная, когда применять float, Decimal или Fraction, вы избежите проблем с округлением, получите корректные отчёты и предсказуемые вычисления.

Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (https://myrusakov.ru)!

Добавляйтесь ко мне в друзья ВКонтакте: https://vk.com/myrusakov.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: https://vk.com/rusakovmy.

Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления

Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.

Порекомендуйте эту статью друзьям:

Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):

  1. Кнопка:

    Она выглядит вот так: Как создать свой сайт

  2. Текстовая ссылка:

    Она выглядит вот так: Как создать свой сайт

  3. BB-код ссылки для форумов (например, можете поставить её в подписи):

Комментарии (0):

Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.