"""A representation of the two's complement format used for INT8.""" | |
from dataclasses import dataclass | |
from functools import total_ordering | |
from typing import Any | |
@dataclass | |
class TwosComplementFormat: | |
"""Can be used to express any two's complement signed integer.""" | |
width: int | |
@property | |
def abs_min(self) -> float: | |
"""Absolute minimum representable value.""" | |
return 1 | |
@property | |
def abs_max(self) -> float: | |
"""Absolute maximum representable value.""" | |
return float(2 ** (self.width - 1) - 1) | |
@dataclass | |
class ScaledTwosComplementFormat(TwosComplementFormat): | |
"""A scaled (multiply all values by `scale`) version of `TwosComplementFormat`.""" | |
scale: int | |
@property | |
def abs_min(self) -> float: | |
return super().abs_min * self.scale | |
@property | |
def abs_max(self) -> float: | |
return super().abs_max * self.scale | |
@dataclass | |
@total_ordering | |
class TwosComplementInstance: | |
"""An instance of a number using a (possibly scaled) `TwosComplementFormat`.""" | |
format: TwosComplementFormat | |
uint: int | |
def __post_init__(self) -> None: | |
assert 0 <= self.uint < 2**self.format.width, self.uint | |
@property | |
def value(self) -> float: | |
"""The numerical value of the bitstring, | |
as defined by the two's complement format. | |
""" | |
if self.uint <= self.format.abs_max: | |
return self.uint | |
return float(self.uint - 2**self.format.width) | |
def __repr__(self) -> str: | |
return str(self.value) | |
def __eq__(self, other: Any) -> bool: | |
return self.value.__eq__(other) | |
def __lt__(self, other: Any) -> bool: | |
return self.value.__lt__(other) |