将 Long/ULong 转换为带有填充零的无符号十六进制字符串

Posted

技术标签:

【中文标题】将 Long/ULong 转换为带有填充零的无符号十六进制字符串【英文标题】:Convert a Long/ULong to an unsigned hexadecimal string with padding zeros 【发布时间】:2019-05-31 02:56:01 【问题描述】:

如何将表示无符号长整数的Long/ULong 转换为带有填充零的无符号十六进制字符串(16 位十六进制字符串)?

我正在寻找一个使用 Kotlin 或 Java 的简单而整洁的解决方案。

【问题讨论】:

【参考方案1】:
val mutableList = listOf(121212L, 121212121212L,-1L)
mutableList.forEach 
    println(it.toULong().toString(16).padStart(16, '0'))

它给了

000000000001d97c
0000001c38ce307c
ffffffffffffffff

已编辑:感谢 Ilya 在评论中缺少 toULong 部分。

【讨论】:

这不适用于负长表示的数字(大于或等于 2^63)。例如,对于存储为 -1 的数字,我想要“ffffffffffffffff”,但此解决方案给出“00000000000000-1”。 这里唯一缺少的部分是在调用 toString 之前将 long 值转换为 ULong:it.toULong().toString(16).padStart(16, '0') 虽然这个解决方案比我在下面使用String.format 找到的解决方案更长而且看起来更复杂,但它只运行了运行我的解决方案所需时间的大约 10%。这可能是因为解析格式字符串很慢。所以这确实是一个更好的答案。【参考方案2】:

我在String.format() 中使用x/X 找到了解决方案:

fun Long.to16DigitUnsignedLowercaseHexString() =
    "%016x".format(this)

fun Long.to16DigitUnsignedUppercaseHexString() =
    "%016X".format(this)

我已经测试它适用于边界值0L1LLong.MAX_VALUE-1LLong.MIN_VALUE,所以应该没有问题。

java - How can I pad an integer with zeros on the left? - Stack Overflow 中提出了类似的问题。第一次看到这个时,我没想到它会起作用,因为我认为x/X 用于有符号的十六进制格式。原来我错了,x/X 正好是无符号十六进制格式。

【讨论】:

以上是关于将 Long/ULong 转换为带有填充零的无符号十六进制字符串的主要内容,如果未能解决你的问题,请参考以下文章

C#如何把INT类型转换为方法参数对应的枚举类型?怎么强制转换?

超过16位的字符串装16进制

在 Rust 中将二进制字符串转换为带有前导零的十六进制字符串

填充数字格式的时间表达式,具有带前导零的可变分隔符

在 C# 中添加 long/ulong SSE 不会引发溢出异常?

将十进制转换为小数点后两个零的字符串,和逗号? C# [重复]