Округление чисел в Python: что делает функция round

0
13

Содержание

Краткая памятка по работе с функцией round

  1. Помните, что round в Python 3 использует банковское округление (round half to even).
  2. Для математического округления используйте Decimal с ROUND_HALF_UP.
  3. Для денежных расчетов всегда используйте Decimal или целые числа (копейки/центы).
  4. Округляйте только один раз на границе вычислений, избегайте многократного округления.
  5. Для массивов используйте numpy.round вместо встроенного round.
  6. Документируйте политику округления в коде для других разработчиков.
  7. При сравнении чисел с плавающей точкой сначала округляйте их до нужной точности.
  8. Используйте отрицательные значения ndigits для округления до десятков, сотен и т.д.
  9. Для квантизации (приведения к шагу) используйте комбинацию round и деления.
  10. Логируйте результаты с контролем точности для отладки.
  11. Избегайте использования float для финансовых операций.
  12. Проверяйте граничные случаи (0.5, 1.5, 2.5) при тестировании.

Круглый()

Python round() - изображение номер один
Python round() — изображение номер один

Round() — встроенная функция, доступная в Python. Он вернет вам число с плавающей запятой, которое будет округлено до десятичных знаков, заданных в качестве входных данных.

Если десятичные знаки для округления не указаны, оно считается равным 0 и округляется до ближайшего целого числа.

Описание:

Python - изображение номер два
Python — изображение номер два

Функция round() вернет число, округленное до точности ndigits после десятичной точки. Если аргумент ndigits опущен или None, то вернет ближайшее целое число.

Функция round() округляет значения до ближайшего кратного 10 к степени минус ndigits. Если два кратных одинаково близки, округление производится в сторону чётного, например: round(0.5) и round(-0.5) будет 0, a round(1.5) будет равно 2. Аргумент ndigits принимает целочисленное значение (положительное, нулевое или отрицательное). Возвращаемое значение является целым числом, если второй аргумент ndigits=None или не указан. В противном случае возвращаемое значение имеет тот же тип, что и число, переданное функции round() в качестве округляемого.

Пользовательский тип данных может определить метод __round__(), чтобы влиять на результат функции.

Поведение встроенной функции round() для типа float может быть неожиданным: например, round(2.675, 2) вернёт 2.67 вместо ожидаемого 2.68. Это не ошибка: это результат того факта, что большинство десятичных дробей не может быть представлено в точности как число с плавающей точкой.

Важная семантика "половинок"

Функция round() в - изображение номер три
Функция round() в — изображение номер три

Python использует банковское округление: ties to even («0.5 к ближайшему чётному»).

Это нормально для статистики/агрегаций (уменьшает систематическое смещение), но часто не то, что ждут в финансовых правилах (там нередко требуется HALF_UP: 2.5 => 3).

"Привести к дискретной сетке" (квантизация измерений/шагов)

Day 105 : round function 😵 💫 - изображение номер четыре
Day 105 : round function 😵 💫 — изображение номер четыре

Если доменная модель говорит «точность 0.01/0.1/1 единица», округление логично.

Стабилизация результатов перед сравнением/бакетизацией (не для денег)

round built-in functions in - изображение номер пять
round built-in functions in — изображение номер пять

Иногда нужно сгладить шум float перед группировкой/ключами (но лучше понимать последствия).

# Группировка по шагу 0.01 key = round(value, 2) buckets[key].append(item)

Продакшн-нюанс: если ключи критичны, часто лучше перейти на целые (масштабирование) или Decimal, чтобы избежать сюрпризов бинарного float.

Деньги и биллинг на float

How - изображение номер шесть
How — изображение номер шесть

Главная ловушка: float хранится в двоичном виде, многие «красивые» десятичные дроби представлены приблизительно. Из-за этого:

  • хранить в целых минимальных единицах (центы) или
  • использовать + явный режим округления.
ЧИТАТЬ ТАКЖЕ:  Python sort и sorted: в чем разница и как выбрать метод сортировки

Округлять один раз — на границе

How to - изображение номер семь
How to — изображение номер семь

Частая ошибка: округлять промежуточные значения много раз (накопление погрешности/смещения).

# Плохо: много ранних округлений subtotal = round(a, 2) + round(b, 2) # Лучше: считать точно и округлять на выходе subtotal = a + b subtotal_out = round(subtotal, 2)

Если домен требует округления на каждом шаге (например, по регламенту) — это уже явное правило, его нужно задокументировать и тестировать.

Для денег — "integer cents" (самый надёжный и быстрый)

Solved - изображение номер восемь
Solved — изображение номер восемь

# хранение в центах price_cents = 1999 # €19.99 tax_rate = 21 # % tax_cents = (price_cents * tax_rate + 50) // 100 # пример HALF_UP на целых total_cents = price_cents + tax_cents

Комментарий: формула зависит от нужного правила округления (HALF_UP/…); важно, что float не участвует.

Для денег/тарифов — Decimal + quantize (явная политика)

Questions about python3 in round rounding function - изображение номер девять
Questions about python3 in round rounding function — изображение номер девять

from decimal import Decimal, ROUND_HALF_UP amount = Decimal(«2.675») amount_q = (Decimal(«0.01»), rounding=ROUND_HALF_UP) # 2.68

  • десятичная арифметика,
  • вы контролируете режим округления.

Документировать политику округления

Using - изображение номер десять
Using — изображение номер десять

В продакшне округление — это часть бизнес-логики. Практика: вынести в функцию с именем, отражающим правило.

from decimal import Decimal, ROUND_HALF_EVEN TWOPLACES = Decimal(«0.01») def money_round_bankers(x: Decimal) -> Decimal: # Банковское округление до копеек return (TWOPLACES, rounding=ROUND_HALF_EVEN)

Логирование/отчёт с контролем точности (представление)

Логирование в приложениях - изображение номер одиннадцать
Логирование в приложениях — изображение номер одиннадцать

value = compute() # строка — через форматирование line = f»result={value:.3f}» # округление для вывода # число — через round (если наружу нужно именно число) payload = {«result»: round(value, 3)}

Снэппинг к шагу (не обязательно десятичные знаки)

Т критерий - изображение номер двенадцать
Т критерий — изображение номер двенадцать

Если шаг не равен 10^-n, round(x, ndigits) не подходит напрямую. Делают масштабирование:

Комментарий: на float возможны артефакты (вроде 1.2000000000002). Для строгой десятичной сетки лучше Decimal.

Описание

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

Второй аргумент является необязательным и по умолчанию равен 0, если он не указан, и в этом случае он округляется до ближайшего целого числа, а тип возвращаемого значения также будет целым числом.

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

  • >=5, чем +1 будет добавлено к окончательному значению
  • <5, чем будет возвращено окончательное значение, поскольку оно соответствует указанным десятичным знакам.

Возвращаемое значение

Функция np - изображение номер четырнадцать
Функция np — изображение номер четырнадцать

Он вернет целое значение, если num_of_decimals не указано, и значение с плавающей запятой, если указано num_of_decimals. Обратите внимание, что значение будет округлено до +1, если значение после десятичной точки >=5, в противном случае оно вернет значение до указанных десятичных знаков.

Сокращение

Round - изображение номер пятнадцать
Round — изображение номер пятнадцать

Сокращение используется для уменьшения размеров элементов. Это самый простой способ округления до конкретного числа. Для положительных чисел функция округляет их до ближайшего целого в меньшую сторону, а для отрицательных — в большую.

Например, round(565.5556, -2) используется как функция сокращения. Она вернет 600.

Пример №1 — функция round помогает при работе с дробями

Математика в - изображение номер шестнадцать
Математика в — изображение номер шестнадцать

Когда дроби нельзя конвертировать в десятичные дроби, в дело вступает функция round. После десятичной точки обычно много цифр, как например в случае с 22/7 (Pi). Но обычно используется не больше 2-4 цифр. Вспомогательный встроенный в round тип будет округлять до ближайшего кратного 10.

round(3.675, 2) вернет 3,67, а не 3,68. Удивительно, но это не баг. Результат указывает на то, что большая часть дробей не могут считаться точными числами с плавающей точкой.

Пример №2 — оба параметра

C++ - изображение номер семнадцать
C++ — изображение номер семнадцать

a = 5.465 print(round(a, 2)) b = 5.476 print(round(b, 2)) c = 5.473 print(round(c, 2))

Пример №2 — исключения и ошибки

Урок 1 - изображение номер восемнадцать
Урок 1 — изображение номер восемнадцать

tup = (-40.95, 50.85, 10.98, 20.26, 30.05) lis = [-39.29, -42.15, -39.97, -10.98, 32.65] print(‘Округление отрицательного десятичного числа = %.2f’ %round(-19.48476)) print(‘Округление положительного десятичного числа = %.2f’ %round(15.98763)) print(‘Округление со вторым параметром при положительном значении = %.3f’ %round(11.98763, 3)) print(‘Округление со вторым параметром при отрицательном значении = %.3f’ %round(-18.48476, 3)) print(‘Округление элементов в списке = %d’ %round(lis[2])) print(‘Округление элементов в списке = %d’ %round(lis[4])) print(‘Округление элементов в кортеже = %d’ %round(tup[2])) print(‘Округление элементов в кортеже = %d’ %round(tup[4])) print(‘Округление сумы чисел = %.2f’ %round(20 + 40 — 20.6578, 2))

ЧИТАТЬ ТАКЖЕ:  Перевод секунд в часы, минуты и секунды на Python: формулы и примеры

Округление отрицательного десятичного числа = -19.00 Округление положительного десятичного числа = 16.00 Округление со вторым параметром при положительном значении = 11.988 Округление со вторым параметром при отрицательном значении = -18.485 Округление элементов в списке = -40 Округление элементов в списке = 33 Округление элементов в кортеже = 11 Округление элементов в кортеже = 30 Округление сумы чисел = 39.34

Есть разные метода функции округления в Python. Одна из них — это сокращение.

Насколько сильное влияние может оказать округление? (Округление против усечения)

Точность и ошибки округления в - изображение номер девятнадцать
Точность и ошибки округления в — изображение номер девятнадцать

Лучшим примером влияния округления является фондовый рынок. В прошлом, то есть в 1982 году, Ванкуверская фондовая биржа (VSE): используется для усечения стоимости акций до трех десятичных знаков в каждой сделке.

Это повторялось почти 3000 раз каждый день. Накопленные сокращения приводят к потере около 25 пунктов в месяц.

Считайте числа с плавающей запятой, созданные ниже, ценами акций. Прямо сейчас я генерирую его для диапазона

Чтобы продемонстрировать влияние округления, я написал небольшой фрагмент кода, в котором сначала вам нужно использовать числа только до 3 знаков после запятой, то есть усекая число после 3 знаков после запятой.

У меня есть исходное общее значение, общее количество, полученное из усеченных значений, и разница между исходным и усеченным значением.

Для того же набора чисел я использовал метод round() до 3 десятичных знаков и вычислял сумму и разницу между исходным значением и округленным значением.

Разница между оригиналом и после усечения составляет 499.9016193868665, а после округления — 0.04661938686695066.

Разница кажется очень большой, и пример показывает, как метод round() помогает производить вычисления, близкие к точности.

Пример: округление целых значений

Если вам случится использовать round() для целочисленного значения, он просто вернет вам число без каких-либо изменений.

Пример: округление в отрицательную сторону Numbers

Давайте посмотрим несколько примеров того, как округляется отрицательные числа.

Пример: круглые массивы Numpy

#python : #numpy - изображение номер двадцать два
#python : #numpy — изображение номер двадцать два

Чтобы решить эту проблему, мы можем использовать модуль numpy и метод () или (), как показано в примере ниже.

Мы также можем использовать (), который дает тот же результат, что показан в примере ниже.

Пример: Десятичный модуль

В дополнение к функции round() в Python есть десятичный модуль, который помогает более точно обрабатывать десятичные числа.

  • ROUND_CEILING: округляется в сторону бесконечности,
  • ROUND_DOWN: округляет значение в сторону нуля,
  • ROUND_FLOOR: округляется в сторону -бесконечности,
  • ROUND_HALF_DOWN: округляется до ближайшего значения, приближающегося к нулю,
  • ROUND_HALF_EVEN: округляется до ближайшего целого числа,
  • ROUND_HALF_UP: округляется до ближайшего значения, отходящего от нуля.
  • ROUND_UP: округление происходит в том месте, где значение будет отличаться от нуля.

В десятичном формате метод quantize() помогает округлять до фиксированного количества десятичных знаков, и вы можете указать, какое округление будет использоваться, как показано в примере ниже. Пример: Использование методов round() и decimal

Часто задаваемые вопросы о функции round в Python

Вопрос: Как работает банковское округление в Python?
Ответ: В Python 3 функция round использует банковское округление (round half to even), когда число находится ровно посередине между двумя целыми, оно округляется до ближайшего четного числа.

Вопрос: Почему round(2.5) возвращает 2, а не 3?
Ответ: Потому что Python использует банковское округление. 2.5 находится ровно посередине между 2 и 3, и по правилу round half to even округление идет в сторону четного числа, то есть к 2.

Вопрос: Можно ли изменить поведение round на математическое округление?
Ответ: Да, для этого нужно использовать модуль Decimal с явным указанием политики округления ROUND_HALF_UP.

Вопрос: Как округлить число до двух знаков после запятой?
Ответ: Используйте round(число, 2). Например, round(3.14159, 2) вернет 3.14.

Вопрос: Что произойдет, если передать в round отрицательное число знаков?
Ответ: Отрицательное значение ndigits округляет до десятков, сотен и т.д. Например, round(1234, -2) вернет 1200.

Вопрос: Почему round(1.5) возвращает 2, а round(2.5) возвращает 2?
Ответ: Это особенность банковского округления: 1.5 округляется до 2 (четное), 2.5 тоже округляется до 2 (четное).

Вопрос: Как правильно округлять денежные значения в Python?
Ответ: Для денег рекомендуется использовать Decimal с quantize и явной политикой округления, либо работать с целыми числами (копейками/центами).

Вопрос: Влияет ли функция round на производительность при работе с большими массивами?
Ответ: Да, для массивов лучше использовать numpy.round, который оптимизирован для векторных операций.

Вопрос: Как округлить число вниз (всегда к меньшему)?
Ответ: Используйте math.floor() для округления вниз или модуль Decimal с политикой ROUND_DOWN.

Вопрос: Чем отличается round от int() при преобразовании float?
Ответ: int() просто отбрасывает дробную часть (усечение), а round() производит математическое округление по правилам банковского округления.