fix #15257, toHex couldn't handle large uint64 (#15261) [backport:1.2]

This commit is contained in:
Miran
2020-09-04 09:23:27 +02:00
committed by GitHub
parent 48f2997221
commit 4fb17bc03b
2 changed files with 35 additions and 14 deletions

View File

@@ -938,6 +938,31 @@ proc toOct*(x: BiggestInt, len: Positive): string {.noSideEffect,
inc shift, 3
mask = mask shl BiggestUInt(3)
proc toHexImpl(x: BiggestUInt, len: Positive, handleNegative: bool): string {.noSideEffect.} =
const
HexChars = "0123456789ABCDEF"
var n = x
result = newString(len)
for j in countdown(len-1, 0):
result[j] = HexChars[int(n and 0xF)]
n = n shr 4
# handle negative overflow
if n == 0 and handleNegative: n = not(BiggestUInt 0)
proc toHex*(x: BiggestUInt, len: Positive): string {.noSideEffect.} =
## Converts `x` to its hexadecimal representation.
##
## The resulting string will be exactly `len` characters long. No prefix like
## ``0x`` is generated.
runnableExamples:
let
a = 62'u64
b = 4097'u64
doAssert a.toHex(3) == "03E"
doAssert b.toHex(3) == "001"
doAssert b.toHex(4) == "1001"
toHexImpl(x, len, false)
proc toHex*(x: BiggestInt, len: Positive): string {.noSideEffect,
rtl, extern: "nsuToHex".} =
## Converts `x` to its hexadecimal representation.
@@ -948,25 +973,19 @@ proc toHex*(x: BiggestInt, len: Positive): string {.noSideEffect,
let
a = 62
b = 4097
c = -8
doAssert a.toHex(3) == "03E"
doAssert b.toHex(3) == "001"
doAssert b.toHex(4) == "1001"
const
HexChars = "0123456789ABCDEF"
var
n = x
result = newString(len)
for j in countdown(len-1, 0):
result[j] = HexChars[int(n and 0xF)]
n = n shr 4
# handle negative overflow
if n == 0 and x < 0: n = -1
doAssert c.toHex(6) == "FFFFF8"
toHexImpl(cast[BiggestUInt](x), len, x < 0)
proc toHex*[T: SomeInteger](x: T): string =
proc toHex*[T: SomeInteger](x: T): string {.noSideEffect.} =
## Shortcut for ``toHex(x, T.sizeof * 2)``
runnableExamples:
doAssert toHex(1984'i64) == "00000000000007C0"
toHex(BiggestInt(x), T.sizeof * 2)
doAssert toHex(1984'i16) == "07C0"
toHexImpl(cast[BiggestUInt](x), 2*sizeof(T), x < 0)
proc toHex*(s: string): string {.noSideEffect, rtl.} =
## Converts a bytes string to its hexadecimal representation.

View File

@@ -3,8 +3,6 @@
import
strutils
import macros
template rejectParse(e) =
try:
discard e
@@ -296,6 +294,10 @@ assert "/1/2/3".rfind('0') == -1
assert(toHex(100i16, 32) == "00000000000000000000000000000064")
assert(toHex(-100i16, 32) == "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C")
assert(toHex(high(uint64)) == "FFFFFFFFFFFFFFFF")
assert(toHex(high(uint64), 16) == "FFFFFFFFFFFFFFFF")
assert(toHex(high(uint64), 32) == "0000000000000000FFFFFFFFFFFFFFFF")
assert "".parseHexStr == ""
assert "00Ff80".parseHexStr == "\0\xFF\x80"
try: