1,461 bytes · the Python implementation · view raw
from .math_round_div_types import RoundingMode
def round_div(numerator: int, denominator: int, mode: RoundingMode = "half-up") -> int:
"""Divide two integers, rounding according to ``mode``. Money is held in minor units (pence, cents) as integers. Every rate, discount and tax calculation eventually needs to divide, and that division is where rounding policy lives. Making it explicit here means a system can state its policy once instead of scattering ``round()`` through a codebase. """if isinstance(numerator, bool) or isinstance(denominator, bool):
raise TypeError("round_div operates on integers only")
ifnot isinstance(numerator, int) ornot isinstance(denominator, int):
raise TypeError("round_div operates on integers only")
if denominator == 0:
raise ValueError("denominator must not be zero")
negative = (numerator < 0) != (denominator < 0)
n = abs(numerator)
d = abs(denominator)
quotient, remainder = divmod(n, d)
twice = remainder * 2if mode == "down":
passelif mode == "up":
if remainder > 0:
quotient += 1elif mode == "half-even":
if twice > d or (twice == d and quotient % 2 == 1):
quotient += 1elif mode == "half-up":
if twice >= d:
quotient += 1else:
raise ValueError('unknown rounding mode "%s"' % mode)
return -quotient if negative else quotient