bug 92 workaround

This commit is contained in:
jangko 2023-06-14 13:22:52 +07:00
parent c748d9afb7
commit 1ce276db1e
No known key found for this signature in database
GPG Key ID: 31702AE10541E6B9
2 changed files with 15 additions and 23 deletions

View File

@ -9,17 +9,12 @@
import
# Standard library
typetraits, algorithm, hashes,
# Status libraries
# stew/byteutils,
std/[typetraits, algorithm, hashes],
# Internal
./private/datatypes,
# ./private/int_negabs,
# ./private/compiletime_helpers,
# ./intops,
./uintops, ./endians2
from stew/byteutils import toHex # Why are we exporting readHexChar in byteutils?
from stew/byteutils import toHex
template leastSignificantWord*(a: SomeBigInteger): Word =
a.limbs[0]
@ -33,20 +28,10 @@ template signedWordType*(_: type SomeBigInteger): type =
template wordType*(_: type SomeBigInteger): type =
Word
template static_check_size(T: typedesc[SomeInteger], bits: static[int]) =
# To avoid a costly runtime check, we refuse storing into StUint types smaller
# than the input type.
static: doAssert sizeof(T) * 8 <= bits, "Input type (" & $T &
") cannot be stored in a multi-precision " &
$bits & "-bit integer." &
"\nUse a smaller input type instead. This is a compile-time check" &
" to avoid a costly run-time bit_length check at each StUint initialization."
func stuint*[T: SomeInteger](n: T, bits: static[int]): StUint[bits] {.inline.}=
## Converts an integer to an arbitrary precision integer.
when sizeof(n) > sizeof(Word):
result.limbs[0] = Word(n and Word.high)
result.limbs[0] = Word(n and Word.high.T)
result.limbs[1] = Word(n shr WordBitWidth)
else:
result.limbs[0] = Word(n)
@ -57,7 +42,11 @@ func stint*[T: SomeInteger](n: T, bits: static[int]): StInt[bits] {.inline.}=
result.imp = stuint(n, bits)
else:
if n < 0:
result.imp = stuint(-n, bits)
if n == low(T):
# special case, bug #92 workaround
result.imp = stuint(high(T), bits) + stuint(1, bits)
else:
result.imp = stuint(-n, bits)
result.negate
else:
result.imp = stuint(n, bits)

View File

@ -90,12 +90,15 @@ template testAddSub(chk, tst: untyped) =
chkNegation(chk, 127, -127, 128)
chkNegation(chk, 32768, -32768, 128)
chkNegation(chk, 32767, -32767, 128)
# With Nim 1.6, it seems like https://github.com/status-im/nim-stint/issues/92
# can now happen on 32-bit platforms.
#when (NimMajor,NimMinor,NimPatch) < (1,6,0):
chkNegation(chk, 2147483648, -2147483648, 128)
chkNegation(chk, 2147483647, -2147483647, 128)
# chkNegation(chk, 9223372036854775808, -9223372036854775808, 128) # TODO: bug #92
let x = int64.high.i128
chk -x == -9223372036854775807'i64.i128
let y = int64.low.i128
let z = int64.high.i128 + 1.i128
chk -y == z
tst "absolute integer":
chkAbs(chk, 0, 0, 128)