From e2f107d1bbe57d78b66694a53723aca61a296859 Mon Sep 17 00:00:00 2001 From: Simon Forman Date: Tue, 4 Oct 2022 08:47:39 -0700 Subject: [PATCH] Subtraction. --- bigjoyints/big.py | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/bigjoyints/big.py b/bigjoyints/big.py index a388aaa..48de59c 100644 --- a/bigjoyints/big.py +++ b/bigjoyints/big.py @@ -1,6 +1,10 @@ import ctypes +def is_i32(n): + return -2**31 <= n < 2**31 + + class OberonInt: ''' Let's model the Oberon RISC integers, @@ -8,7 +12,7 @@ class OberonInt: ''' def __init__(self, initial=0): - assert -2**31 <= initial < 2**31 + assert is_i32(initial) self.value = ctypes.c_int32(initial) assert self.value.value == initial @@ -18,15 +22,19 @@ class OberonInt: ''' assert isinstance(other, OberonInt) n = self.value.value + other.value.value - carry = not (-2**31 <= n < 2**31) + carry = not is_i32(n) if carry: n &= (2**31-1) - return carry, OberonInt(n) + return int(carry), OberonInt(n) def negate(self): # Instead of binary ops, just cheat: return OberonInt(-self.value.value) + def sub(self, other): + assert isinstance(other, OberonInt) + return self.add(other.negate()) + def __repr__(self): #b = bin(self.value.value & (2**32-1)) return f'OberonInt({self.value.value})' @@ -36,23 +44,40 @@ class OberonInt: return self.value.value == other.value.value -one = OberonInt(1) -obmin, zero, obmax = map(OberonInt, ( +obmin, zero, one, obmax = map(OberonInt, ( -(2**31), 0, + 1, 2**31-1, )) +# Addition carry, z = obmax.add(one) assert carry assert z == zero +# Negation negative_one = one.negate() carry, m = obmin.add(negative_one) assert carry assert m == obmax +# Ergo, subtraction. +carry, m = obmin.sub(one) +assert carry +assert m == obmax + + +carry, hmm = obmax.add(obmax) +assert carry +assert hmm.value.value == 2**31 - 2 +carry, eh = obmax.sub(hmm) +assert not carry +assert eh == one +assert hmm.add(one)[1] == obmax + + ## if initial >= 2**31: ## raise ValueError(f'too big: {initial!r}') ## if initial < -2**31: -- 2.11.0