Почему round(2.675, 2) выводит 2.67

Почему round(2.675, 2) выводит 2.67

@python_quiz

Разберем этот квиз

Коротко: код

python

выведет 2.67. Ниже объясню подробно, почему так происходит, разберу варианты ответов и покажу способы получить «ожидаемое» 2.68 в тех случаях, где это важно.

Что делает код

Функция round(x, 2) округляет число x до двух знаков после запятой. Интуитивно многие ждут, что 2.675 округлится до 2.68. Но результат зависит от того, как число представлено в памяти.

Причина: представление чисел с плавающей запятой

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

Проверим, как выглядит x в деталях:

python

Пример вывода (на вашей системе формат будет таким же по сути):

Как видно, значение в памяти чуть меньше 2.675 (примерно 2.6749999999999998). Поэтому round видит число ближе к 2.67 и округляет в эту сторону.

Анализ вариантов (кратко)

  • 2.67 — соответствует фактическому выводу программы (из-за двоичного приближения число оказалось чуть меньше).
  • 2.68 — это то, чего ожидают многие, если думать в чисто десятичной логике; возможно получить, но не с float 2.675 напрямую.
  • 2.70 — неверно: это округление до одного знака после запятой и не связано с текущей задачей.
  • «Ошибка округления» — не происходит исключение; просто нюанс представления чисел.

Как получить «правильное» десятичное округление

Если вам важно округлять именно в десятичном смысле (например, для денег), используйте модуль decimal и создавайте Decimal из строки, а не из float.

Пример с Decimal:

python

Важно: если вы создадите Decimal из самого float, результат будет повторять двоичную погрешность:

python

Поэтому всегда используйте Decimal('2.675') (строку), когда нужна точная десятичная арифметика.

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

Вывод

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

Report Page