From 8ea95078f4f18c26a7563417d814e1a5759fac5f Mon Sep 17 00:00:00 2001 From: jangko Date: Wed, 14 Jun 2023 07:38:23 +0700 Subject: [PATCH] signed int addsub --- stint/intops.nim | 37 ++++++++++++++++++++--------------- stint/uintops.nim | 13 ++++++++---- tests/test_int_addsub.nim | 30 ++++++++++++++-------------- tests/test_int_comparison.nim | 1 - 4 files changed, 45 insertions(+), 36 deletions(-) diff --git a/stint/intops.nim b/stint/intops.nim index 1822202..834d5e8 100644 --- a/stint/intops.nim +++ b/stint/intops.nim @@ -30,7 +30,7 @@ func sign*(a: StInt): int = else: -1 func isNegative*(a: StInt): bool = - a.sign < 0 + a.limbs[^1] >= signMask func clearMSB(a: var StInt) = a.limbs[^1] = a.limbs[^1] and clearSignMask @@ -107,14 +107,11 @@ func `==`*(a, b: StInt): bool = func `<`*(a, b: StInt): bool = ## Unsigned `less than` comparison let - aSign = a.sign - bSign = b.sign + aNeg = a.isNegative + bNeg = b.isNegative - if aSign >= 0: - if bSign < 0: - return false - elif bSign >= 0: - return true + if aNeg xor bNeg: + return aNeg a.imp < b.imp @@ -174,40 +171,48 @@ func `shl`*(a: StInt, k: SomeInteger): StInt = ## Shift left by k bits result.imp.shiftLeft(a.imp, k) +func setBit*(a: var StInt, k: Natural) = + a.imp.setBit(k) + +func clearBit*(a: var StInt, k: Natural) = + a.imp.clearBit(k) + +func getBit*(a: StInt, k: Natural): bool = + a.imp.getBit(k) + {.pop.} # Addsub # -------------------------------------------------------- {.push raises: [], inline, noinit, gcsafe.} -#[ func `+`*(a, b: StInt): StInt = ## Addition for multi-precision unsigned int - result.sum(a, b) + result.imp.sum(a.imp, b.imp) func `+=`*(a: var StInt, b: StInt) = ## In-place addition for multi-precision unsigned int - a.sum(a, b) + a.imp.sum(a.imp, b.imp) func `-`*(a, b: StInt): StInt = ## Substraction for multi-precision unsigned int - result.diff(a, b) + result.imp.diff(a.imp, b.imp) func `-=`*(a: var StInt, b: StInt) = ## In-place substraction for multi-precision unsigned int - a.diff(a, b) + a.imp.diff(a.imp, b.imp) func inc*(a: var StInt, w: Word = 1) = + a.imp.inc(w) func `+`*(a: StInt, b: SomeUnsignedInt): StInt = ## Addition for multi-precision unsigned int ## with an unsigned integer - result.sum(a, Word(b)) + result.imp.sum(a.imp, Word(b)) func `+=`*(a: var StInt, b: SomeUnsignedInt) = ## In-place addition for multi-precision unsigned int ## with an unsigned integer - a.inc(Word(b)) -]# + a.imp.inc(Word(b)) {.pop.} \ No newline at end of file diff --git a/stint/uintops.nim b/stint/uintops.nim index 7ae5163..0e31571 100644 --- a/stint/uintops.nim +++ b/stint/uintops.nim @@ -126,24 +126,29 @@ export {.push raises: [], inline, gcsafe.} -func `shr`*(a: StUint, k: SomeInteger): StUint = +func `shr`*(a: StUint, k: Natural): StUint = ## Shift right by k bits result.shiftRight(a, k) -func `shl`*(a: StUint, k: SomeInteger): StUint = +func `shl`*(a: StUint, k: Natural): StUint = ## Shift left by k bits result.shiftLeft(a, k) -func setBit*(a: var StUint, k: SomeInteger) = +func setBit*(a: var StUint, k: Natural) = let limbIndex = k div WordBitWidth let bitIndex = k mod WordBitWidth setBit(a.limbs[limbIndex], bitIndex) -func clearBit*(a: var StUint, k: SomeInteger) = +func clearBit*(a: var StUint, k: Natural) = let limbIndex = k div WordBitWidth let bitIndex = k mod WordBitWidth clearBit(a.limbs[limbIndex], bitIndex) +func getBit*(a: StUint, k: Natural): bool = + let limbIndex = k div WordBitWidth + let bitIndex = k mod WordBitWidth + getBit(a.limbs[limbIndex], bitIndex) + {.pop.} # Addsub diff --git a/tests/test_int_addsub.nim b/tests/test_int_addsub.nim index 46e59f2..cd99636 100644 --- a/tests/test_int_addsub.nim +++ b/tests/test_int_addsub.nim @@ -122,42 +122,42 @@ proc main() = suite "Testing signed addition implementation": test "In-place addition gives expected result": - var a = 20182018.stint(64) - let b = 20172017.stint(64) + var a = 20182018.stint(256) + let b = 20172017.stint(256) a += b - check: cast[int64](a) == 20182018'i64 + 20172017'i64 + check a == (20182018'i64 + 20172017'i64).i256 test "Addition gives expected result": - let a = 20182018.stint(64) - let b = 20172017.stint(64) + let a = 20182018.stint(256) + let b = 20172017.stint(256) - check: cast[int64](a+b) == 20182018'i64 + 20172017'i64 + check a+b == (20182018'i64 + 20172017'i64).i256 test "When the low half overflows, it is properly carried": # uint8 (low half) overflow at 255 - let a = 100'i16.stint(16) - let b = 100'i16.stint(16) + let a = 100.stint(256) + let b = 100.stint(256) - check: cast[int16](a+b) == 200 + check a+b == 200.i256 suite "Testing signed substraction implementation": test "In-place substraction gives expected result": - var a = 20182018.stint(64) - let b = 20172017.stint(64) + var a = 20182018.stint(256) + let b = 20172017.stint(256) a -= b - check: cast[int64](a) == 20182018'i64 - 20172017'i64 + check a == (20182018'i64 - 20172017'i64).i256 test "Substraction gives expected result": - let a = 20182018.stint(64) - let b = 20172017.stint(64) + let a = 20182018.stint(256) + let b = 20172017.stint(256) - check: cast[int64](a-b) == 20182018'i64 - 20172017'i64 + check: a-b == (20182018'i64 - 20172017'i64).i256 main() diff --git a/tests/test_int_comparison.nim b/tests/test_int_comparison.nim index f43f796..0f7b291 100644 --- a/tests/test_int_comparison.nim +++ b/tests/test_int_comparison.nim @@ -274,7 +274,6 @@ proc main() = suite "Wider signed int comparison coverage": testComparison(check, test) - suite "Signed int - Testing comparison operators": let a = 10.i256