Functional Weave
Code in TypeScript

math.round-div@1.0.0

impl/python.py

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")
    if not isinstance(numerator, int) or not 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 * 2

    if mode == "down":
        pass
    elif mode == "up":
        if remainder > 0:
            quotient += 1
    elif mode == "half-even":
        if twice > d or (twice == d and quotient % 2 == 1):
            quotient += 1
    elif mode == "half-up":
        if twice >= d:
            quotient += 1
    else:
        raise ValueError('unknown rounding mode "%s"' % mode)

    return -quotient if negative else quotient