BigInts in terms of Oberon Ints
Oberon RISC has Two's Complement 32-bit ints with carry. So far so good.
This commit is contained in:
parent
56fdf1eb18
commit
6ecf681d3a
|
|
@ -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}')
|
||||
Loading…
Reference in New Issue