Грешка при закръгляване в Python с нечетно число?

Аз съм начинаещ в Python и имам един въпрос.
Защо закръгляването на число като 5.5, 7.5, (каквото и да е).5 с нечетна цяло число, прилагащо round(num), работи правилно (правило 5/4), но закръгляването на число като (всичко).5 с нечетна цяло число от същата функция връща само цяло число? (Но ако добавим малко число като 0,000000001 към това десетично число, то работи правилно)

Имам предвид следното:

round(9.5)

връща 10 и е правилно. Но

round(8.5)

връща 8 и не е правилно. И

round(8.5 + 0.0000000000001)

връща 9.

Защо работи неправилно?
Използвам Python 3.2.2 в Windows.


person Ivan Akulov    schedule 10.04.2012    source източник
comment
интересно Python 2.7 връща 10.0 за round(9.5) и 9.0 за round(8.5).   -  person Tim Pietzcker    schedule 10.04.2012
comment
round(8.5) връща 9.0, както се очаква. Аз съм с версия 2.7.2.   -  person Mike McMahon    schedule 10.04.2012


Отговори (1)


Python 3.x, за разлика от Python 2.x, използва закръгляване на банкера за round() функция.

Това е документирано поведение:

[I]ако две кратни са еднакво близки, закръгляването се извършва към четния избор (така, например, както round(0,5), така и round(-0,5) са 0, а round(1,5) е 2).

Тъй като числата с плаваща запетая по самото си естество са само приближения, не би трябвало да има голямо значение как се третират „точните“ полуцели числа – така или иначе винаги може да има грешки при закръгляване в предходните изчисления.

Редактиране: За да получите старото поведение на закръгляване, можете да използвате

def my_round(x):
    return int(x + math.copysign(0.5, x))
person Sven Marnach    schedule 10.04.2012
comment
тъкмо щях да публикувам това бижу :) - person Mike McMahon; 10.04.2012
comment
интересно 2to3 справя ли се с това? - person Mark Ransom; 10.04.2012
comment
@MarkRansom: Не. Но мисля, че ако вашият код разчита на това, той така или иначе е повреден. - person Sven Marnach; 10.04.2012
comment
И каква функция мога да използвам, за да направя нормално закръгляване като в Python 2.7? - person Ivan Akulov; 10.04.2012
comment
@SvenMarnach, понякога не става въпрос да разчитате на резултатите, а по-скоро да преминете тестовете или да накарате клиентите ви да се оплачат от промяна. - person Mark Ransom; 10.04.2012
comment
@gxoptg: опитайте def roundHalfUp(f): return round(f + 0.00000000000001) или def roundHalfUp(f): return math.floor(f + 0.5) - person jedwards; 10.04.2012
comment
max(round(x), round(x + 1) - 1) дава неправилни резултати за отрицателни числа. - person agf; 10.04.2012
comment
За да обобщим причината за закръгляването по този начин: ако x.5 числата са значителна част от някои данни, закръгляването на всички нагоре също измества средната стойност нагоре. Но ако закръглите половината от тях нагоре и половината надолу, средната стойност трябва да остане приблизително същата. - person Thomas K; 10.04.2012
comment
@MarkRansom: Не, 2to3 не се занимава с грешки в Python 2, които се коригират в Python 3. ;-) - person Lennart Regebro; 11.04.2012
comment
@jedwards: Точно като моя първи опит, тези решения не работят по същия начин като Python 2 round() за отрицателни числа. - person Sven Marnach; 11.04.2012
comment
Поведението на Python 3.9 изглежда се различава в зависимост от това дали закръглявате до цяло число или до десетична; определено има някакво неочаквано поведение тук: round(1.05, 1) => 1.1 , round(1.15, 1) => 1.1 , но round(10.5) => 10, round(11.5) => 12 - person Oskar Austegard; 21.05.2021
comment
@OskarAustegard Това се дължи на естеството на числата с плаваща запетая. Десетичното число 1,05 не може да бъде точно представено в двоично число с плаваща запетая, така че се закръгля до най-близката стойност, която може да бъде представена, която се оказва 1,050000000000000444089209850062616169452667236328125. Тъй като това е малко повече от 1,05, то се закръгля нагоре. По същия начин 1,15 се закръгля до 1,149999999999999911182158029987476766109466552734375, когато десетичният низ се анализира в число с плаваща запетая, така че се закръгля надолу. - person Sven Marnach; 21.05.2021
comment
Цялото нещо е доста спорно поради тази причина. По-голямата част от десетичните числа не могат да бъдат точно представени като двоични числа с плаваща запетая, така че винаги имаме работа със закръглени числа. - person Sven Marnach; 21.05.2021
comment
Ето как да видите до какво се закръгляват деикмалните числа: ideone.com/WR6FWU - person Sven Marnach; 21.05.2021