
Go 的 strconv.ParseInt 不支持直接解析高位为 1 的十六进制字符串为负数 int64,正确做法是先用 ParseUint 解析为 uint64,再通过类型转换获得补码语义下的正确 int64 值。
go 的 `strconv.parseint` 不支持直接解析高位为 1 的十六进制字符串为负数 int64,正确做法是先用 `parseuint` 解析为 uint64,再通过类型转换获得补码语义下的正确 int64 值。
在 Go 中,strconv.ParseInt(s, base, bitSize) 要求输入字符串表示的数值在目标有符号整数的数学值范围内(即 −2⁶³ 到 2⁶³−1)。但十六进制字符串如 "ff11223344556677" 对应的无符号数值为 0xff11223344556677 ≈ 1.83 × 10¹⁹,已远超 int64 的最大正数 9223372036854775807,因此 ParseInt(..., 16, 64) 直接报 strconv.ErrRange。
真正需要的不是“数学上相等的有符号数”,而是按 64 位二进制补码解释该字节序列所得的有符号整数值。此时应分两步处理:
- 使用 strconv.ParseUint(s, 16, 64) 将字符串无符号解析为 uint64(它接受 0x00–0xffffffffffffffff 全范围);
- 将得到的 uint64 值直接转为 int64:Go 规范保证该转换是位模式保持(bit-preserving) 的,即底层 64 位比特完全复用,CPU 自动按补码规则解释,从而得到正确的负值。
以下是完整示例代码:
package main
import (
"fmt"
"strconv"
)
func hexStringToInt64(s string) (int64, error) {
u, err := strconv.ParseUint(s, 16, 64)
if err != nil {
return 0, err
}
return int64(u), nil
}
func main() {
s := "ff11223344556677"
i, err := hexStringToInt64(s)
if err != nil {
panic(err)
}
fmt.Printf("Hex: %s → int64: %d\n", s, i) // 输出: Hex: ff11223344556677 → int64: -67234915848722825
}⚠️ 注意事项:
- 此方法仅适用于已知输入为合法 64 位十六进制字符串(长度 ≤ 16,字符在 0-9a-fA-F 范围内);
- 若需支持带符号前缀(如 -0xff),应先预处理——ParseInt 适合此类场景,但本例中原始字符串无符号前缀;
- 不要使用 unsafe 或手动位运算:uint64 → int64 的直接转换是标准、安全且零开销的;
- 验证时可反向检查:fmt.Sprintf("%016x", uint64(i)) 应与原始小写十六进制字符串一致(忽略大小写和前导零)。
该方案简洁、高效、符合 Go 类型系统设计,是处理补码语义十六进制解析的标准实践。


















