From fb797d225e2f085d085fe582e9b1665c4a037abb Mon Sep 17 00:00:00 2001 From: jangko Date: Tue, 13 Jun 2023 19:51:49 +0700 Subject: [PATCH] signed int initialization --- stint/intops.nim | 12 +++---- stint/private/datatypes.nim | 10 ++++-- stint/uintops.nim | 13 ++++++- tests/test_int_initialization.nim | 57 +++++++++++++++++++++++++++++++ tests/test_int_signedness.nim | 8 ----- 5 files changed, 83 insertions(+), 17 deletions(-) create mode 100644 tests/test_int_initialization.nim diff --git a/stint/intops.nim b/stint/intops.nim index 293c3b4..6e730b4 100644 --- a/stint/intops.nim +++ b/stint/intops.nim @@ -32,11 +32,11 @@ func sign*(a: StInt): int = func isNegative*(a: StInt): bool = a.sign < 0 -func clearSign(a: var StInt) = - a.limbs[^1] = a.limbs[^1] and clearSignMask +func clearMSB(a: var StInt) = + a.limbs[0] = a.limbs[0] and clearSignMask -func setSign(a: var StInt) = - a.limbs[^1] = a.limbs[^1] or signMask +func setMSB(a: var StInt) = + a.limbs[0] = a.limbs[0] or signMask func negate*(a: var StInt) = a.imp.bitnot(a.imp) @@ -82,14 +82,14 @@ func high*[bits](_: typedesc[StInt[bits]]): StInt[bits] = # so we only have to unset the most significant bit. for i in 0 ..< result.limbs.len: result[i] = high(Word) - result.clearSign + result.clearMSB func low*[bits](_: typedesc[StInt[bits]]): StInt[bits] = # The lowest signed int has representation # 0b1000_0000_0000_0000 .... # so we only have to set the most significant bit. result.setZero - result.setSign + result.setMSB {.pop.} diff --git a/stint/private/datatypes.nim b/stint/private/datatypes.nim index b485ab0..115db6f 100644 --- a/stint/private/datatypes.nim +++ b/stint/private/datatypes.nim @@ -97,11 +97,17 @@ func usedBitsAndWords*(a: openArray[Word]): tuple[bits, words: int] = template limbs*(a: StInt): untyped = # TODO: remove this when we switch to borrow `.` a.imp.limbs + +template `[]`*(a: StInt, i: SomeInteger or BackwardsIndex): Word = + a.imp.limbs[i] + +template `[]=`*(a: var StInt, i: SomeInteger or BackwardsIndex, val: Word) = + a.imp.limbs[i] = val -template `[]`*(a: SomeBigInteger, i: SomeInteger or BackwardsIndex): Word = +template `[]`*(a: StUInt, i: SomeInteger or BackwardsIndex): Word = a.limbs[i] -template `[]=`*(a: var SomeBigInteger, i: SomeInteger or BackwardsIndex, val: Word) = +template `[]=`*(a: var StUInt, i: SomeInteger or BackwardsIndex, val: Word) = a.limbs[i] = val # Iterations diff --git a/stint/uintops.nim b/stint/uintops.nim index bedccce..7ae5163 100644 --- a/stint/uintops.nim +++ b/stint/uintops.nim @@ -15,7 +15,8 @@ import ./private/uint_addsub, ./private/uint_mul, ./private/uint_div, - ./private/primitives/addcarry_subborrow + ./private/primitives/addcarry_subborrow, + stew/bitops2 export StUint @@ -133,6 +134,16 @@ func `shl`*(a: StUint, k: SomeInteger): StUint = ## Shift left by k bits result.shiftLeft(a, k) +func setBit*(a: var StUint, k: SomeInteger) = + let limbIndex = k div WordBitWidth + let bitIndex = k mod WordBitWidth + setBit(a.limbs[limbIndex], bitIndex) + +func clearBit*(a: var StUint, k: SomeInteger) = + let limbIndex = k div WordBitWidth + let bitIndex = k mod WordBitWidth + clearBit(a.limbs[limbIndex], bitIndex) + {.pop.} # Addsub diff --git a/tests/test_int_initialization.nim b/tests/test_int_initialization.nim new file mode 100644 index 0000000..a2ef940 --- /dev/null +++ b/tests/test_int_initialization.nim @@ -0,0 +1,57 @@ +# Stint +# Copyright 2018-2023 Status Research & Development GmbH +# Licensed under either of +# +# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) +# * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) +# +# at your option. This file may not be copied, modified, or distributed except according to those terms. + +import ../stint, unittest, test_helpers + +template testInitialization(chk, tst: untyped) = + tst "zero one": + var a: StInt[128] + a.setZero + chk a == 0.i128 + + var b: StInt[256] + b.setZero + chk b == 0.i256 + + var aa: StInt[128] + aa.setOne + chk aa == 1.i128 + + var bb: StInt[256] + bb.setOne + chk bb == 1.i256 + + var xx = StInt[128].zero + chk xx == 0.i128 + + var yy = StInt[256].zero + chk yy == 0.i256 + + var uu = StInt[128].one + chk uu == 1.i128 + + var vv = StInt[256].one + chk vv == 1.i256 + + tst "hi lo": + let x = Int128.high + var z = UInt128.high + z.clearBit(0) + chk x.imp == z + + let xx = Int128.low + var zz = UInt128.low + zz.setBit(0) + chk xx.imp == zz + +static: + testInitialization(ctCheck, ctTest) + +suite "Signed integer initialization": + testInitialization(check, test) diff --git a/tests/test_int_signedness.nim b/tests/test_int_signedness.nim index 8e78a12..8efe690 100644 --- a/tests/test_int_signedness.nim +++ b/tests/test_int_signedness.nim @@ -9,14 +9,6 @@ import ../stint, unittest, test_helpers -#[ -template chkAddition(chk, a, b, c, bits: untyped) = - block: - let x = stuint(a, bits) - let y = stuint(b, bits) - chk x + y == stuint(c, bits) -]# - template testSignedness(chk, tst: untyped) = tst "positive sign": let a = stint(1, 128)