By default, Python's fractions.Fraction
rounds halves to the nearest even number. If you, instead, want to round a fraction but send halves up, here's how that's done:
from math import floor
from fractions import Fraction
_ONEHALF = Fraction(1, 2)
def roundhalfup(x: Fraction) -> int:
"""
Rounds x to the nearest integer, with ties being rounded towards positive infinity
"""
return floor(x + _ONEHALF)
Since fractions.Fraction
implements .__floor__
itself, this does give precise results. At no point is the number converted into a float
or other approximation.
Even if you're not dealing directly in Fraction
s, the library can still be useful:
def divroundhalfup(a: int, b: int) -> int:
"""
Returns the nearest integer to exactly a/b, with ties rounded up
"""
return floor(Fraction(2*a + b, 2*b))