diff --git a/bigjoyints/big.py b/bigjoyints/big.py new file mode 100644 index 0000000..a388aaa --- /dev/null +++ b/bigjoyints/big.py @@ -0,0 +1,59 @@ +import ctypes + + +class OberonInt: + ''' + Let's model the Oberon RISC integers, + 32-bit, two's complement. + ''' + + def __init__(self, initial=0): + assert -2**31 <= initial < 2**31 + self.value = ctypes.c_int32(initial) + assert self.value.value == initial + + def add(self, other): + ''' + Return carry bit and new value. + ''' + assert isinstance(other, OberonInt) + n = self.value.value + other.value.value + carry = not (-2**31 <= n < 2**31) + if carry: + n &= (2**31-1) + return carry, OberonInt(n) + + def negate(self): + # Instead of binary ops, just cheat: + return OberonInt(-self.value.value) + + def __repr__(self): + #b = bin(self.value.value & (2**32-1)) + return f'OberonInt({self.value.value})' + + def __eq__(self, other): + assert isinstance(other, OberonInt) + return self.value.value == other.value.value + + +one = OberonInt(1) +obmin, zero, obmax = map(OberonInt, ( + -(2**31), + 0, + 2**31-1, + )) + + +carry, z = obmax.add(one) +assert carry +assert z == zero + +negative_one = one.negate() +carry, m = obmin.add(negative_one) +assert carry +assert m == obmax + +## if initial >= 2**31: +## raise ValueError(f'too big: {initial!r}') +## if initial < -2**31: +## raise ValueError(f'too small: {initial!r}')