Вчера потратил пару часов, отлаживая алгоритм на Python из-за того, что несмотря на шаг в минус один, округлённое значение после двойки сразу скатывалось в 0. Пока не решил проверить, как происходит округление.
Со школы помню, что 0.5 математически округляется в большую сторону, если прямо не заявлено округление методом отброса дробной части. Оказалось, мои знания старомодны. В части именно числа 0.5 есть ряд новых вариантов (может они и не новы, но мимо меня прошли).
- Банковское округление (англ. banker’s rounding) — округление для этого случая происходит к ближайшему чётному, то есть 2,5 → 2, 3,5 → 4.
- Случайное округление — округление происходит в меньшую или большую сторону в случайном порядке, но с равной вероятностью (может использоваться в статистике). Также часто используется округление с неравными вероятностями (вероятность округления вверх равна дробной части), этот способ делает накопление ошибок случайной величиной с нулевым математическим ожиданием.
- Чередующееся округление — округление происходит в меньшую или большую сторону поочерёдно.
Недостатком математического округления является то, что при округлении большого числа значений, которые далее будут обрабатываться совместно, может происходить накопление ошибки округления. Типичный пример: округление до целых рублей денежных сумм, выражаемых в рублях и копейках. В реестре из 10 000 строк (если считать копеечную часть каждой суммы случайным числом с равномерным распределением, что обычно вполне допустимо) окажется в среднем около 100 строк с суммами, содержащими в части копеек значение 50. При округлении всех таких строк по правилам математического округления «вверх» сумма «итого» по округлённому реестру окажется на 50 рублей больше чем реальная.
Оказывется Powershell также «по-банковски» округляет.
Вот же ж ты… За столько лет ни разу не столкнулся.