You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 8 x64中BigInteger.Parse十六进制转十进制负数问题求助

.NET 8 x64中BigInteger.Parse解析十六进制为负数的问题及解决方案

问题原因

BigInteger是.NET中的有符号任意精度整数类型,当使用NumberStyles.HexNumber解析十六进制字符串时,解析逻辑会将字符串视为有符号数的十六进制补码表示。如果十六进制字符串的最高位字符是8-F(对应二进制最高位为1),解析器会将其识别为负数,从而得到错误的负数值;而添加前导零后,最高位变为0(二进制最高位为0),就会被解析为正确的正数。

比如示例中的9F4F4108B0BC1F2E02662669A635B9C,最高位是9,二进制为1001,被解析为负数;添加前导零后最高位为0,解析结果正确。

严谨解决方案

方法1:通过字节数组构造无符号BigInteger(推荐)

利用BigInteger的构造函数,将十六进制字符串转为字节数组后,指定isUnsigned: true参数(.NET Core 2.1及以上支持),直接解析为无符号数:

public static BigInteger ParseHexAsUnsigned(string hexStr)
{
    if (string.IsNullOrWhiteSpace(hexStr))
        throw new ArgumentException("十六进制字符串不能为空", nameof(hexStr));

    // 处理奇数长度的字符串,补前导零保证字节转换正确
    if (hexStr.Length % 2 != 0)
    {
        hexStr = "0" + hexStr;
    }

    // 将十六进制字符串转为大端字节数组
    byte[] bigEndianBytes = new byte[hexStr.Length / 2];
    for (int i = 0; i < hexStr.Length; i += 2)
    {
        bigEndianBytes[i / 2] = Convert.ToByte(hexStr.Substring(i, 2), 16);
    }

    // BigInteger构造函数默认使用小端字节序,因此需要反转数组
    Array.Reverse(bigEndianBytes);
    return new BigInteger(bigEndianBytes, isUnsigned: true);
}

方法2:自动补前导零处理字符串

检测十六进制字符串的最高位,若为8-F则添加前导零,确保解析时被视为正数:

public static BigInteger ParseHexAsUnsigned(string hexStr)
{
    if (string.IsNullOrWhiteSpace(hexStr))
        throw new ArgumentException("十六进制字符串不能为空", nameof(hexStr));

    // 若最高位是8-F,添加前导零
    if ("89ABCDEFabcdef".IndexOf(hexStr[0]) != -1)
    {
        hexStr = "0" + hexStr;
    }

    return BigInteger.Parse(hexStr, System.Globalization.NumberStyles.HexNumber);
}

验证示例

对于十六进制字符串D0752364CFB600E410619304BE135C,使用上述任一方法均可得到正确结果:1082373592684167505354120550330274652。

内容的提问来源于stack exchange,提问作者JRrelyea

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 04:47:14