Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting a hex string to its BigInteger equivalent negates the value

Tags:

c#

biginteger

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?

like image 657
Babalola Rotimi Avatar asked May 08 '15 08:05

Babalola Rotimi


People also ask

How to Parse BigInteger in Java?

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.

What is BigInteger c#?

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).


2 Answers

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.

like image 103
Nathan Cooper Avatar answered Oct 16 '22 20:10

Nathan Cooper


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);
like image 3
James Barrass Avatar answered Oct 16 '22 20:10

James Barrass