diff options
-rw-r--r-- | lib/pure/strutils.nim | 43 | ||||
-rw-r--r-- | tests/stdlib/tstrutil.nim | 6 |
2 files changed, 35 insertions, 14 deletions
diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim index a0a172430..20010ff81 100644 --- a/lib/pure/strutils.nim +++ b/lib/pure/strutils.nim @@ -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. diff --git a/tests/stdlib/tstrutil.nim b/tests/stdlib/tstrutil.nim index 5702b7341..ef5b041be 100644 --- a/tests/stdlib/tstrutil.nim +++ b/tests/stdlib/tstrutil.nim @@ -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: |