You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

十六进制数相加结果异常:计算"920001A"+"920001F"输出不符预期

解决BigInteger十六进制加法结果不符合预期的问题

这个问题的核心在于BigInteger对十六进制字符串的默认解析规则——它会把最高位为1的十六进制数当成有符号负数处理,导致你的加法结果和预期不符。让我给你拆解原因并提供解决方案:

问题根源

你使用NumberStyles.HexNumber解析的两个十六进制数:920001A920001F,它们的最高位都是9(二进制表示的最高位是1)。BigInteger默认会将这类十六进制字符串解析为有符号的负数

  • 920001A被解析为十进制的 -109065078
  • 920001F被解析为十进制的 -109065073

两个负数相加的结果是 -218130151,转换成十六进制补码形式就是你看到的F2400039

解决方案

要让BigInteger把这两个十六进制数当成无符号正数解析,最简单可靠的方法是在十六进制字符串开头补一个0,这样最高位就变成0,避免被识别为负数:

BigInteger number1 = BigInteger.Parse("0920001A", NumberStyles.HexNumber);
BigInteger number2 = BigInteger.Parse("0920001F", NumberStyles.HexNumber);
BigInteger sum = BigInteger.Add(number1, number2);
MessageBox.Show(sum.ToString("X")); // 输出预期的12400039

如果你不想修改原字符串,也可以通过字节数组构造无符号BigInteger(注意BigInteger使用小端字节序):

// 辅助方法:十六进制字符串转字节数组
public static byte[] StringToByteArray(string hex)
{
    // 处理奇数长度的十六进制字符串
    hex = hex.PadLeft((hex.Length + 1) / 2, '0');
    return Enumerable.Range(0, hex.Length)
                     .Where(x => x % 2 == 0)
                     .Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
                     .ToArray();
}

// 构造无符号BigInteger
byte[] bytes1 = StringToByteArray("920001A");
Array.Reverse(bytes1); // 转换为小端字节序
BigInteger number1 = new BigInteger(bytes1);

byte[] bytes2 = StringToByteArray("920001F");
Array.Reverse(bytes2);
BigInteger number2 = new BigInteger(bytes2);

BigInteger sum = BigInteger.Add(number1, number2);
MessageBox.Show(sum.ToString("X")); // 输出12400039

补充说明

BigInteger的Parse方法结合NumberStyles.HexNumber时,遵循的是.NET对有符号数的解析规则:如果十六进制字符串的最高位是8-F(二进制最高位为1),就会被解析为负数。补0后最高位变为0,自然就被当作正数处理,加法结果也就符合你的预期了。

内容的提问来源于stack exchange,提问作者Chetan.B

火山引擎 最新活动