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?
Firstly, take two BigInteger objects and set values. BigInteger one, two; one = new BigInteger("99"); two = new BigInteger("978"); Now, parse BigInteger object “two” into Binary. two = new BigInteger("1111010010", 2); String str = two.
The BigInteger type is an immutable type that represents an arbitrarily large integer whose value in theory has no upper or lower bounds. The members of the BigInteger type closely parallel those of other integral types (the Byte, Int16, Int32, Int64, SByte, UInt16, UInt32, and UInt64 types).
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
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.
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.
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.
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.
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.
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.
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.
string big = "91";
BigInteger big1 = BigInteger.Parse(big, System.Globalization.NumberStyles.AllowHexSpecifier);
Console.WriteLine("{0}={1}", big, big1);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With