четверг, 10 ноября 2016 г.

Python: округление

Выяснилась интересная особенность. В python 2.7 округление выполняется как учили в школе, где число x.5 округляется до (x+1):
>>> print round(0.5), round(1.5)
1.0 2.0

В python 3.3 поведение этой функции изменилось:
>>> print ( round(0.5), round(1.5) )
0 2
то есть, во-первых, по умолчанию возвращается целое число, и, главное, выполняется bankers rounding (банковское округление, в котором x.5 округляется до ближайшего четного).

Как эту печаль обойти штатными срадствами, не нашел, поэтому пока пользуюсь таким костыликом:
def round27 (number, ndigits=0):
    result = round(number, ndigits)
    if abs(result) >= abs(number): return result
    delta = abs(number) - abs(result)
    if ndigits >= 0:
        multiplier = 10.0**(ndigits+1)
        if abs(number)*multiplier-abs(result)*multiplier == 5.0:
            result = number + (delta if number >= 0 else -delta)
    else:
        multiplier = 10.0**(-ndigits-1)
        if abs(number)-abs(result) == 5.0*multiplier:
            result = number + (delta if number >= 0 else -delta)
    return result

Вообще, оказывается, есть даже стандарт IEEE 754, в котором все эти правила округления указаны. Надо глянуть, может, и ГОСТ найдётся.

UPD. Нашелся вот такой документ: СТ СЭВ 543-77 Числа. Правила записи и округления
Тут как раз округление по правилу "половины дальше от нуля".

Комментариев нет:

Отправить комментарий