summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--lib/pure/strutils.nim43
-rw-r--r--tests/stdlib/tstrutil.nim6
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: