将十六进制字符串转换为其BigInteger等效值会使该值无效

时间:2021-06-30 16:48:02

I have a string which represents a large hexadecimal number which I want to convert to an integer. When I try to convert though, the answer for the integer equivalent is negative. Here's the code:

我有一个字符串,表示我想要转换为整数的大十六进制数。当我尝试转换时,等价整数的答案是否定的。这是代码:

string hex = "9782E78F1636";

BigInteger b1 = BigInteger.Parse(hex, NumberStyles.AllowHexSpecifier);

How can I get the correct result?

我怎样才能得到正确的结果?

3 个解决方案

#1


You need to prepend a 0 to the string. While this number works with long.Parse, with BigInt you get a negative number if the first digit is between 8-F

您需要在字符串前加0。虽然这个数字适用于long.Parse,但如果第一个数字介于8-F之间,则BigInt会得到一个负数

string hex = "09782E78F1636";
      BigInteger b1 = BigInteger.Parse(hex,NumberStyles.AllowHexSpecifier);
    Console.WriteLine(b1);

It's been a long time, but I feel like I should have explained why:

这已经很久了,但我觉得我应该解释原因:

Signed integers use the Most Significant Bit (MSB) indicates whether a value is positive or negative. Although there's more to it than just the msb.

有符号整数使用最高有效位(MSB)指示值是正还是负。虽然它不仅仅是msb。

Both BigInteger and long are signed integers: If the most significant number in the hex string is between 0 (0000) and 7 (0111), the msb is 0 and the number is positive. If it's 8 (1000) or above, the msb is 1 and the number is negative.

BigInteger和long都是有符号整数:如果十六进制字符串中的最高有效数字介于0(0000)和7(0111)之间,则msb为0且数字为正数。如果它是8(1000)或更高,则msb为1且数字为负。

long.Parse knows the size of the type you're parsing, ie that it's hex representation is 00009782E78F1636. The msb is 0 so it's clealy positive.

long.Parse知道你正在解析的类型的大小,即它的十六进制表示是00009782E78F1636。 msb为0所以它是正面的。

BigInt isn't of a fixed size like long. If you give it 9782E78F1636 it doesn't know you mean the same as 00001782E78F1636. It thinks the type is just shorter. It's expecting a signed value and it thinks you mean the first bit of the 9 (1001) to be the sign. Adding a zero to the front 09782E78F1636 makes it clear that the MSL bit is 0 and the 1001 is just part of the actual value.

BigInt不像长的固定大小。如果您给它9782E78F1636它不知道您的意思与00001782E78F1636相同。它认为类型只是更短。它期待一个有符号的值,它认为你的意思是9(1001)的第一位是标志。向前面添加零09782E78F1636清楚地表明MSL位为0且1001只是实际值的一部分。

#2


Try below:

var b1 = BigInteger.Parse("0" + hex, NumberStyles.HexNumber);

Bare in mind that you will need to prepend a 0 to the hex string. You will get a negative number if the first digit is between 8-F

请记住,您需要在十六进制字符串前加上0。如果第一个数字在8-F之间,您将得到一个负数

#3


Your leading character is between 8 and F, That means as a signed number it's negative. This isn't special to BigInteger, it happens with all the integer types. It's how they represent negative numbers in binary; using the most significant bit.

你的主角在8到F之间,这意味着作为有符号数字它是负数。这对BigInteger来说并不特殊,它适用于所有整数类型。这就是他们如何用二进制表示负数;使用最重要的位。

For most types the location of the MSB depends on the size of the type, provided you use all the bits if the first character is between 8 and F you'll get a negative number.

对于大多数类型,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);

The BigInteger isn't necessarily big, it's arbitrary in size and it'll use enough bytes to fit the number it's given, so to fill up it's bytes and set the MSB so it's negative it's just the first character it comes across. If your number is unsigned you'll need to add a 0 to the start of the string.

BigInteger不一定很大,它的大小是任意的,并且它会使用足够的字节来适应它给出的数字,所以要填充它的字节并设置MSB使其为负值,它只是它遇到的第一个字符。如果您的号码是无符号的,则需要在字符串的开头添加0。

        string big = "91";
        BigInteger big1 = BigInteger.Parse(big, System.Globalization.NumberStyles.AllowHexSpecifier);
        Console.WriteLine("{0}={1}", big, big1);

#1


You need to prepend a 0 to the string. While this number works with long.Parse, with BigInt you get a negative number if the first digit is between 8-F

您需要在字符串前加0。虽然这个数字适用于long.Parse,但如果第一个数字介于8-F之间,则BigInt会得到一个负数

string hex = "09782E78F1636";
      BigInteger b1 = BigInteger.Parse(hex,NumberStyles.AllowHexSpecifier);
    Console.WriteLine(b1);

It's been a long time, but I feel like I should have explained why:

这已经很久了,但我觉得我应该解释原因:

Signed integers use the Most Significant Bit (MSB) indicates whether a value is positive or negative. Although there's more to it than just the msb.

有符号整数使用最高有效位(MSB)指示值是正还是负。虽然它不仅仅是msb。

Both BigInteger and long are signed integers: If the most significant number in the hex string is between 0 (0000) and 7 (0111), the msb is 0 and the number is positive. If it's 8 (1000) or above, the msb is 1 and the number is negative.

BigInteger和long都是有符号整数:如果十六进制字符串中的最高有效数字介于0(0000)和7(0111)之间,则msb为0且数字为正数。如果它是8(1000)或更高,则msb为1且数字为负。

long.Parse knows the size of the type you're parsing, ie that it's hex representation is 00009782E78F1636. The msb is 0 so it's clealy positive.

long.Parse知道你正在解析的类型的大小,即它的十六进制表示是00009782E78F1636。 msb为0所以它是正面的。

BigInt isn't of a fixed size like long. If you give it 9782E78F1636 it doesn't know you mean the same as 00001782E78F1636. It thinks the type is just shorter. It's expecting a signed value and it thinks you mean the first bit of the 9 (1001) to be the sign. Adding a zero to the front 09782E78F1636 makes it clear that the MSL bit is 0 and the 1001 is just part of the actual value.

BigInt不像长的固定大小。如果您给它9782E78F1636它不知道您的意思与00001782E78F1636相同。它认为类型只是更短。它期待一个有符号的值,它认为你的意思是9(1001)的第一位是标志。向前面添加零09782E78F1636清楚地表明MSL位为0且1001只是实际值的一部分。

#2


Try below:

var b1 = BigInteger.Parse("0" + hex, NumberStyles.HexNumber);

Bare in mind that you will need to prepend a 0 to the hex string. You will get a negative number if the first digit is between 8-F

请记住,您需要在十六进制字符串前加上0。如果第一个数字在8-F之间,您将得到一个负数

#3


Your leading character is between 8 and F, That means as a signed number it's negative. This isn't special to BigInteger, it happens with all the integer types. It's how they represent negative numbers in binary; using the most significant bit.

你的主角在8到F之间,这意味着作为有符号数字它是负数。这对BigInteger来说并不特殊,它适用于所有整数类型。这就是他们如何用二进制表示负数;使用最重要的位。

For most types the location of the MSB depends on the size of the type, provided you use all the bits if the first character is between 8 and F you'll get a negative number.

对于大多数类型,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);

The BigInteger isn't necessarily big, it's arbitrary in size and it'll use enough bytes to fit the number it's given, so to fill up it's bytes and set the MSB so it's negative it's just the first character it comes across. If your number is unsigned you'll need to add a 0 to the start of the string.

BigInteger不一定很大,它的大小是任意的,并且它会使用足够的字节来适应它给出的数字,所以要填充它的字节并设置MSB使其为负值,它只是它遇到的第一个字符。如果您的号码是无符号的,则需要在字符串的开头添加0。

        string big = "91";
        BigInteger big1 = BigInteger.Parse(big, System.Globalization.NumberStyles.AllowHexSpecifier);
        Console.WriteLine("{0}={1}", big, big1);