Вопросы и задачки для подготовки к собеседованиям и прокачки навыков
Разместить рекламу: @tproger_sales_bot
Правила общения: https://tprg.ru/rules
Другие каналы: @tproger_channels
Другие наши проекты: https://tprg.ru/media
Post #4528
661
Встроенная функция 𝚛𝚘𝚞𝚗𝚍() в Python 3 округляет до ближайшего чётного числа. В английском это называют «banker's rounding» т.е. банковское округление.
Развёрнутое пояснение
1️⃣Значение 𝟶.𝟻 находится ровно посередине между 𝟶 и 𝟷; ближайшее чётное — 𝟶, поэтому 𝚊 получает 𝟶.
2️⃣Значение 𝟷.𝟻 находится посередине между 𝟷 и 𝟸; ближайшее чётное — 𝟸, поэтому 𝚋 получает 𝟸.
3️⃣Значение 𝟸.𝟻 находится посередине между 𝟸 и 𝟹; ближайшее чётное — 𝟸, поэтому 𝚌 тоже получает 𝟸.
4️⃣Функция print(a, b, c) выводит 0 2 2.
Почему это важно
Многие ожидают «школьного» округления (0.5 → 1), но Python 3 намеренно использует банковское, чтобы минимизировать накопление ошибки при суммировании большого количества округлённых значений. Если нужно классическое округление, придётся писать свою функцию или использовать модуль 𝚍𝚎𝚌𝚒𝚖𝚊𝚕.
А почему ошибка меньше накапливается то?
Я тоже не сразу понял, вот объяснение.
При обычном округлении цифра 5 всегда округляется вверх, и из-за этого возникает перекос — из 10 возможных дробных частей (0,0–0,9) пять округляются вверх (5, 6, 7, 8, 9) и только четыре вниз (1, 2, 3, 4), а ноль не меняется. Когда суммируются тысячи таких округлённых значений, этот небольшой сдвиг накапливается.
Банковское округление решает проблему тем, что числа с дробной частью ровно 0,5 округляются то вверх, то вниз — в зависимости от чётности целой части. Поскольку чётные и нечётные числа встречаются примерно одинаково часто, округления вверх и вниз статистически компенсируют друг друга.
На практике разница существенная: в примере с 1000 числами обычное округление даёт погрешность ~0,1%, а банковское ~0,01% для равномерного набора данных. Подробнее можно почитать в этой статье, например.
Развёрнутое пояснение
1️⃣Значение 𝟶.𝟻 находится ровно посередине между 𝟶 и 𝟷; ближайшее чётное — 𝟶, поэтому 𝚊 получает 𝟶.
2️⃣Значение 𝟷.𝟻 находится посередине между 𝟷 и 𝟸; ближайшее чётное — 𝟸, поэтому 𝚋 получает 𝟸.
3️⃣Значение 𝟸.𝟻 находится посередине между 𝟸 и 𝟹; ближайшее чётное — 𝟸, поэтому 𝚌 тоже получает 𝟸.
4️⃣Функция print(a, b, c) выводит 0 2 2.
Почему это важно
Многие ожидают «школьного» округления (0.5 → 1), но Python 3 намеренно использует банковское, чтобы минимизировать накопление ошибки при суммировании большого количества округлённых значений. Если нужно классическое округление, придётся писать свою функцию или использовать модуль 𝚍𝚎𝚌𝚒𝚖𝚊𝚕.
А почему ошибка меньше накапливается то?
Я тоже не сразу понял, вот объяснение.
При обычном округлении цифра 5 всегда округляется вверх, и из-за этого возникает перекос — из 10 возможных дробных частей (0,0–0,9) пять округляются вверх (5, 6, 7, 8, 9) и только четыре вниз (1, 2, 3, 4), а ноль не меняется. Когда суммируются тысячи таких округлённых значений, этот небольшой сдвиг накапливается.
Банковское округление решает проблему тем, что числа с дробной частью ровно 0,5 округляются то вверх, то вниз — в зависимости от чётности целой части. Поскольку чётные и нечётные числа встречаются примерно одинаково часто, округления вверх и вниз статистически компенсируют друг друга.
На практике разница существенная: в примере с 1000 числами обычное округление даёт погрешность ~0,1%, а банковское ~0,01% для равномерного набора данных. Подробнее можно почитать в этой статье, например.
- ✍ 5
- 👍 2





