Module orca_whirlpool.internal.quote.swap_simulator.bit_math

Expand source code
from ...errors import WhirlpoolError, MathErrorCode


class BitMath:
    @staticmethod
    def mul(n0: int, n1: int, limit: int) -> int:
        result = n0 * n1
        if BitMath.is_over_limit(result, limit):
            raise WhirlpoolError(MathErrorCode.MultiplicationOverflow)
        return result

    @staticmethod
    def mul_div(n0: int, n1: int, d: int, limit: int) -> int:
        return BitMath.mul_div_round_up_if(n0, n1, d, False, limit)

    @staticmethod
    def mul_div_round_up(n0: int, n1: int, d: int, limit: int) -> int:
        return BitMath.mul_div_round_up_if(n0, n1, d, True, limit)

    @staticmethod
    def mul_div_round_up_if(n0: int, n1: int, d: int, round_up: bool, limit: int) -> int:
        if d == 0:
            raise WhirlpoolError(MathErrorCode.DivideByZero)

        p = BitMath.mul(n0, n1, limit)
        n = p // d
        if round_up and p % d != 0:
            return n + 1
        else:
            return n

    @staticmethod
    def div_round_up(n: int, d: int) -> int:
        return BitMath.div_round_up_if(n, d, True)

    @staticmethod
    def div_round_up_if(n: int, d: int, round_up: bool) -> int:
        if d == 0:
            raise WhirlpoolError(MathErrorCode.DivideByZero)

        q = n // d
        if round_up and n % d != 0:
            return q + 1
        else:
            return q

    @staticmethod
    def is_over_limit(n0: int, limit: int) -> bool:
        ulimit_max = 2**limit - 1
        return n0 > ulimit_max

Classes

class BitMath
Expand source code
class BitMath:
    @staticmethod
    def mul(n0: int, n1: int, limit: int) -> int:
        result = n0 * n1
        if BitMath.is_over_limit(result, limit):
            raise WhirlpoolError(MathErrorCode.MultiplicationOverflow)
        return result

    @staticmethod
    def mul_div(n0: int, n1: int, d: int, limit: int) -> int:
        return BitMath.mul_div_round_up_if(n0, n1, d, False, limit)

    @staticmethod
    def mul_div_round_up(n0: int, n1: int, d: int, limit: int) -> int:
        return BitMath.mul_div_round_up_if(n0, n1, d, True, limit)

    @staticmethod
    def mul_div_round_up_if(n0: int, n1: int, d: int, round_up: bool, limit: int) -> int:
        if d == 0:
            raise WhirlpoolError(MathErrorCode.DivideByZero)

        p = BitMath.mul(n0, n1, limit)
        n = p // d
        if round_up and p % d != 0:
            return n + 1
        else:
            return n

    @staticmethod
    def div_round_up(n: int, d: int) -> int:
        return BitMath.div_round_up_if(n, d, True)

    @staticmethod
    def div_round_up_if(n: int, d: int, round_up: bool) -> int:
        if d == 0:
            raise WhirlpoolError(MathErrorCode.DivideByZero)

        q = n // d
        if round_up and n % d != 0:
            return q + 1
        else:
            return q

    @staticmethod
    def is_over_limit(n0: int, limit: int) -> bool:
        ulimit_max = 2**limit - 1
        return n0 > ulimit_max

Static methods

def div_round_up(n: int, d: int) ‑> int
Expand source code
@staticmethod
def div_round_up(n: int, d: int) -> int:
    return BitMath.div_round_up_if(n, d, True)
def div_round_up_if(n: int, d: int, round_up: bool) ‑> int
Expand source code
@staticmethod
def div_round_up_if(n: int, d: int, round_up: bool) -> int:
    if d == 0:
        raise WhirlpoolError(MathErrorCode.DivideByZero)

    q = n // d
    if round_up and n % d != 0:
        return q + 1
    else:
        return q
def is_over_limit(n0: int, limit: int) ‑> bool
Expand source code
@staticmethod
def is_over_limit(n0: int, limit: int) -> bool:
    ulimit_max = 2**limit - 1
    return n0 > ulimit_max
def mul(n0: int, n1: int, limit: int) ‑> int
Expand source code
@staticmethod
def mul(n0: int, n1: int, limit: int) -> int:
    result = n0 * n1
    if BitMath.is_over_limit(result, limit):
        raise WhirlpoolError(MathErrorCode.MultiplicationOverflow)
    return result
def mul_div(n0: int, n1: int, d: int, limit: int) ‑> int
Expand source code
@staticmethod
def mul_div(n0: int, n1: int, d: int, limit: int) -> int:
    return BitMath.mul_div_round_up_if(n0, n1, d, False, limit)
def mul_div_round_up(n0: int, n1: int, d: int, limit: int) ‑> int
Expand source code
@staticmethod
def mul_div_round_up(n0: int, n1: int, d: int, limit: int) -> int:
    return BitMath.mul_div_round_up_if(n0, n1, d, True, limit)
def mul_div_round_up_if(n0: int, n1: int, d: int, round_up: bool, limit: int) ‑> int
Expand source code
@staticmethod
def mul_div_round_up_if(n0: int, n1: int, d: int, round_up: bool, limit: int) -> int:
    if d == 0:
        raise WhirlpoolError(MathErrorCode.DivideByZero)

    p = BitMath.mul(n0, n1, limit)
    n = p // d
    if round_up and p % d != 0:
        return n + 1
    else:
        return n