Use truncate instead of toInt and co

This commit is contained in:
mratsim 2018-10-08 21:04:00 +02:00 committed by tersec
parent 2d6ea71657
commit 4fe901d33b
3 changed files with 31 additions and 39 deletions

View File

@ -73,29 +73,22 @@ func to*(x: SomeInteger, T: typedesc[Stint]): T =
func to*(x: SomeUnsignedInt, T: typedesc[StUint]): T =
stuint(x, result.bits)
func toInt*(num: Stint or StUint): int {.inline.}=
## Returns as int.
## Result is undefined if input does not fit in an int64
cast[int](num.data.leastSignificantWord)
func truncate*(num: Stint or StUint, T: typedesc[int or uint or int64 or uint64]): T {.inline.}=
## Extract the int, uint, int64 or uint64 portion of a multi-precision integer.
## Note that int and uint are 32-bit on 32-bit platform.
## For unsigned result type, result is modulo 2^(sizeof T in bit)
## For signed result type, result is undefined if input does not fit in the target type.
when T is int: cast[int](num.data.leastSignificantWord)
elif T is uint: uint num.data.leastSignificantWord
elif T is int64:
when sizeof(uint) == 8: cast[int64](num.data.leastSignificantWord)
else: cast[int64](num.data.leastSignificantTwoWords)
elif T is uint64:
when sizeof(uint) == 8: uint64 num.data.leastSignificantWord
else: cast[uint64](num.data.leastSignificantTwoWords)
func toUint*(num: Stint or StUint): uint {.inline.}=
## Returns as uint. Result is modulo 2^(sizeof(uint))
num.data.leastSignificantWord.uint
func toInt64*(num: Stint or StUint): int64 {.inline.}=
## Returns as int64.
## Result is undefined if input does not fit in an int64
when sizeof(uint) == 8:
cast[int64](num.data.leastSignificantWord)
else:
cast[int64](num.data.leastSignificantTwoWords)
func toUint64*(num: Stint or StUint): uint64 {.inline.}=
## Returns as uint64. Result is modulo 2^64.
when sizeof(uint) == 8:
num.data.leastSignificantWord.uint64
else:
cast[uint64](num.data.leastSignificantTwoWords)
func toInt*(num: Stint or StUint): int {.inline, deprecated:"Use num.truncate(int) instead".}=
num.truncate(int)
func readHexChar(c: char): int8 {.inline.}=
## Converts an hex char to an int
@ -222,7 +215,7 @@ func toString*[bits: static[int]](num: StUint[bits], radix: static[uint8] = 10):
var (q, r) = divmod(num, base)
while true:
result.add hexChars[r.toInt]
result.add hexChars[r.truncate(int)]
if q.isZero:
break
(q, r) = divmod(q, base)
@ -250,7 +243,7 @@ func toString*[bits: static[int]](num: Stint[bits], radix: static[int8] = 10): s
var (q, r) = divmod(num, base)
while true:
result.add hexChars[r.toInt]
result.add hexChars[r.truncate(int)]
if q.isZero:
break
(q, r) = divmod(q, base)

View File

@ -120,8 +120,7 @@ macro asWordsIterate(wordsIdents: untyped, sid0, sid1, sid2: typed, signed: stat
var w = words[currStint][currDepth]
if currDepth == 0 and signed:
let toInt = bindSym"toInt"
w = quote do: `toInt`(`w`)
w = quote do: toInt(`w`)
replacing.add w

View File

@ -106,21 +106,21 @@ suite "Testing input and output procedures":
check: a.toString == s
check: $a == s
test "toInt, toInt64, toUint, toUint64":
test "Truncate: int, int64, uint, uint64":
block:
let x = 100.stuint(128)
check:
x.toInt == 100
x.toInt64 == 100'i64
x.toUint64 == 100'u64
x.toUint == 100'u
x.truncate(int) == 100
x.truncate(int64) == 100'i64
x.truncate(uint64) == 100'u64
x.truncate(uint) == 100'u
block:
let x = pow(2.stuint(128), 64) + 1
check:
# x.toInt == 1 # This is undefined
# x.toInt64 == 1'i64 # This is undefined
x.toUint64 == 1'u64
x.toUint == 1'u
# x.truncate(int) == 1 # This is undefined
# x.truncate(int64) == 1'i64 # This is undefined
x.truncate(uint64) == 1'u64
x.truncate(uint) == 1'u
test "toInt, toInt64, toUint, toUint64 - word size (32/64-it) specific":
when not defined(stint_test):
@ -130,12 +130,12 @@ suite "Testing input and output procedures":
let x = pow(2.stuint(128), 32) + 1
when sizeof(int) == 4: # 32-bit machines
check:
x.toUint == 1'u
x.toUint64 == 2'u64^32 + 1
x.truncate(uint) == 1'u
x.truncate(uint64) == 2'u64^32 + 1
else:
check:
x.toUint == 2'u^32 + 1
x.toUint64 == 2'u64^32 + 1
x.truncate(uint) == 2'u^32 + 1
x.truncate(uint64) == 2'u64^32 + 1
else:
echo "Next test skipped when Stint forces uint32 backend in test mode"