Skip to content
Snippets Groups Projects
Commit be1a46b6 authored by Frederik Hennig's avatar Frederik Hennig
Browse files

implement C-style integer division and mod

parent 23701cab
No related merge requests found
Pipeline #60075 failed with stages
in 4 minutes and 31 seconds
......@@ -229,6 +229,14 @@ class PsTypedConstant:
def __rsub__(self, other: Any):
return PsTypedConstant(self._rfix(other)._value - self._value, self._dtype)
@staticmethod
def _divrem(dividend, divisor):
quotient = abs(dividend) // abs(divisor)
quotient = quotient if (dividend * divisor > 0) else (- quotient)
rem = abs(dividend) % abs(divisor)
rem = rem if dividend >= 0 else (- rem)
return quotient, rem
def __truediv__(self, other: Any):
if self._dtype.is_float():
......@@ -237,7 +245,10 @@ class PsTypedConstant:
# For unsigned integers, `//` does the correct thing
return PsTypedConstant(self._value // self._fix(other)._value, self._dtype)
elif self._dtype.is_sint():
return NotImplemented # todo: C integer division
dividend = self._value
divisor = self._fix(other)._value
quotient, _ = self._divrem(dividend, divisor)
return PsTypedConstant(quotient, self._dtype)
else:
return NotImplemented
......@@ -247,7 +258,10 @@ class PsTypedConstant:
elif self._dtype.is_uint():
return PsTypedConstant(self._rfix(other)._value // self._value, self._dtype)
elif self._dtype.is_sint():
return NotImplemented # todo: C integer division
dividend = self._fix(other)._value
divisor = self._value
quotient, _ = self._divrem(dividend, divisor)
return PsTypedConstant(quotient, self._dtype)
else:
return NotImplemented
......@@ -255,7 +269,10 @@ class PsTypedConstant:
if self._dtype.is_uint():
return PsTypedConstant(self._value % self._fix(other)._value, self._dtype)
else:
return NotImplemented # todo: C integer division
dividend = self._value
divisor = self._fix(other)._value
_, rem = self._divrem(dividend, divisor)
return PsTypedConstant(rem, self._dtype)
def __neg__(self):
return PsTypedConstant(-self._value, self._dtype)
......
......@@ -16,6 +16,8 @@ class PsAbstractType(ABC):
**Type Equality:** Subclasses must implement `__eq__`, but may rely on `_base_equal` to implement
type equality checks.
**Hashing:** Each subclass that implements `__eq__` must also implement `__hash__`.
"""
def __init__(self, const: bool = False):
......
......@@ -63,8 +63,17 @@ def test_unsigned_integer_division(width):
@pytest.mark.parametrize("width", (8, 16, 32, 64))
def test_signed_integer_division(width):
a = PsTypedConstant(-5, SInt(width))
b = PsTypedConstant(2, SInt(width))
five = PsTypedConstant(5, SInt(width))
two = PsTypedConstant(2, SInt(width))
assert a / b == PsTypedConstant(-2, SInt(width))
assert a % b == PsTypedConstant(-1, SInt(width))
assert five / two == PsTypedConstant(2, SInt(width))
assert five % two == PsTypedConstant(1, SInt(width))
assert (- five) / two == PsTypedConstant(-2, SInt(width))
assert (- five) % two == PsTypedConstant(-1, SInt(width))
assert five / (- two) == PsTypedConstant(-2, SInt(width))
assert five % (- two) == PsTypedConstant(1, SInt(width))
assert (- five) / (- two) == PsTypedConstant(2, SInt(width))
assert (- five) % (- two) == PsTypedConstant(-1, SInt(width))
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment