signed int initialization

This commit is contained in:
jangko 2023-06-13 19:51:49 +07:00
parent 76b2baad6f
commit fb797d225e
No known key found for this signature in database
GPG Key ID: 31702AE10541E6B9
5 changed files with 83 additions and 17 deletions

View File

@ -32,11 +32,11 @@ func sign*(a: StInt): int =
func isNegative*(a: StInt): bool = func isNegative*(a: StInt): bool =
a.sign < 0 a.sign < 0
func clearSign(a: var StInt) = func clearMSB(a: var StInt) =
a.limbs[^1] = a.limbs[^1] and clearSignMask a.limbs[0] = a.limbs[0] and clearSignMask
func setSign(a: var StInt) = func setMSB(a: var StInt) =
a.limbs[^1] = a.limbs[^1] or signMask a.limbs[0] = a.limbs[0] or signMask
func negate*(a: var StInt) = func negate*(a: var StInt) =
a.imp.bitnot(a.imp) 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. # so we only have to unset the most significant bit.
for i in 0 ..< result.limbs.len: for i in 0 ..< result.limbs.len:
result[i] = high(Word) result[i] = high(Word)
result.clearSign result.clearMSB
func low*[bits](_: typedesc[StInt[bits]]): StInt[bits] = func low*[bits](_: typedesc[StInt[bits]]): StInt[bits] =
# The lowest signed int has representation # The lowest signed int has representation
# 0b1000_0000_0000_0000 .... # 0b1000_0000_0000_0000 ....
# so we only have to set the most significant bit. # so we only have to set the most significant bit.
result.setZero result.setZero
result.setSign result.setMSB
{.pop.} {.pop.}

View File

@ -97,11 +97,17 @@ func usedBitsAndWords*(a: openArray[Word]): tuple[bits, words: int] =
template limbs*(a: StInt): untyped = template limbs*(a: StInt): untyped =
# TODO: remove this when we switch to borrow `.` # TODO: remove this when we switch to borrow `.`
a.imp.limbs 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] 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 a.limbs[i] = val
# Iterations # Iterations

View File

@ -15,7 +15,8 @@ import
./private/uint_addsub, ./private/uint_addsub,
./private/uint_mul, ./private/uint_mul,
./private/uint_div, ./private/uint_div,
./private/primitives/addcarry_subborrow ./private/primitives/addcarry_subborrow,
stew/bitops2
export StUint export StUint
@ -133,6 +134,16 @@ func `shl`*(a: StUint, k: SomeInteger): StUint =
## Shift left by k bits ## Shift left by k bits
result.shiftLeft(a, k) 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.} {.pop.}
# Addsub # Addsub

View File

@ -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)

View File

@ -9,14 +9,6 @@
import ../stint, unittest, test_helpers 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) = template testSignedness(chk, tst: untyped) =
tst "positive sign": tst "positive sign":
let a = stint(1, 128) let a = stint(1, 128)