我有一个字符串,表示我想要转换为整数的大十六进制数。当我尝试转换时,等价整数的答案是否定的。这是代码:
string hex = "9782E78F1636";
BigInteger b1 = BigInteger.Parse(hex, NumberStyles.AllowHexSpecifier);
如何获得正确的结果?
答案 0 :(得分:8)
您需要在字符串前加0。虽然此数字适用于long.Parse
,但如果第一个数字介于8-F之间,则BigInt会得到负数。
string hex = "09782E78F1636";
BigInteger b1 = BigInteger.Parse(hex,NumberStyles.AllowHexSpecifier);
Console.WriteLine(b1);
已经很久了,但我觉得我应该解释原因:
Signed integers使用最高有效位(MSB)指示值是正还是负。 Although there's more to it than just the msb
BigInteger
和long
都是有符号整数:如果十六进制字符串中最重要的数字介于0(0000
)和7(0111
)之间,则msb是0
,数字是正数。如果它是8(1000
)或更高,则msb为1
且数字为负。
long.Parse
知道您要解析的类型的大小,即它的十六进制表示是00009782E78F1636
。 msb是0
,所以它是正面的。
BigInt
不像固定大小那样长。如果你给它9782E78F1636
,它就不知道你的意思与00001782E78F1636
相同。它认为类型只是更短。它期望一个有符号的值,它认为你的意思是9(1001
)的第一位是标志。在前面09782E78F1636
添加零可以清楚地表明MSL位是0
而1001
只是实际值的一部分。
答案 1 :(得分:2)
尝试以下:
var b1 = BigInteger.Parse("0" + hex, NumberStyles.HexNumber);
请记住,您需要在十六进制字符串前加上0。 如果第一个数字在8-F
之间,您将得到一个负数答案 2 :(得分:2)
你的主角在8到F之间,这意味着作为带符号的数字,它是否定的。这对BigInteger来说并不特殊,它适用于所有整数类型。它是如何用二进制表示负数的;使用最重要的位。
对于大多数类型,MSB的位置取决于类型的大小,如果您使用所有位,如果第一个字符在8到F之间,则会得到负数。
string b = "91";
SByte b1 = SByte.Parse(b, System.Globalization.NumberStyles.AllowHexSpecifier);
Console.WriteLine("{0}={1}", b, b1);
string s = "9123";
Int16 s1 = Int16.Parse(s, System.Globalization.NumberStyles.AllowHexSpecifier);
Console.WriteLine("{0}={1}", s, s1);
string i = "91234567";
Int32 i1 = Int32.Parse(i, System.Globalization.NumberStyles.AllowHexSpecifier);
Console.WriteLine("{0}={1}", i, i1);
string l = "9123456789012345";
Int64 l1 = Int64.Parse(l, System.Globalization.NumberStyles.AllowHexSpecifier);
Console.WriteLine("{0}={1}", l, l1);
BigInteger不一定是大的,它的大小是任意的,并且它会使用足够的字节来容纳它给出的数字,所以填补它的数量。字节和设置MSB所以它是负面的,它只是它遇到的第一个字符。如果您的号码是未签名的,则需要在字符串的开头添加0。
string big = "91";
BigInteger big1 = BigInteger.Parse(big, System.Globalization.NumberStyles.AllowHexSpecifier);
Console.WriteLine("{0}={1}", big, big1);