From 6ecf681d3a8227c39cb72859a982c6d1ca5ab110 Mon Sep 17 00:00:00 2001 From: Simon Forman Date: Tue, 4 Oct 2022 08:32:04 -0700 Subject: [PATCH] BigInts in terms of Oberon Ints Oberon RISC has Two's Complement 32-bit ints with carry. So far so good. --- bigjoyints/big.py | 59 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 bigjoyints/big.py 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}')