views:

414

answers:

4

Given a potentially huge integer value (in c# string format), I want to be able to generate it's hex equivalent. Normal methods don't apply here as we are talking arbitrarily large numbers, 50 digits or more. The techniques I've seen which use a technique like this:

// Store integer 182
int decValue = 182;
// Convert integer 182 as a hex in a string variable
string hexValue = decValue.ToString("X");
// Convert the hex string back to the number
int decAgain = int.Parse(hexValue, System.Globalization.NumberStyles.HexNumber);

won't work because the integer to convert is too large.

For example I need to be able to convert a string like this:

843370923007003347112437570992242323

to it's hex equivalent.

these don't work:

http://stackoverflow.com/questions/1139957/c-convert-int-to-hex-and-back-again http://stackoverflow.com/questions/74148/how-to-convert-numbers-between-hex-and-decimal-in-c

+5  A: 

Use a BigInteger to store the integer, and than use the .ToString("X") on that object.

Example:

var number = BigInteger.Parse("843370923007003347112437570992242323");
string hexValue = number.ToString("X");

This is however limited to .NET 4 and later. But Jens A. pointed to a BigInteger class on codeproject that class contains a method called ToHexString so that would work for a < .NET 4 scenario.

Davy Landman
Good try, but I'm limited to .NET 3.5 and below
eviljack
There is a good BigInteger implementation for NET 3.5 and lower out here: http://www.codeproject.com/KB/cs/biginteger.aspx
Jens
+2  A: 

As Jens said, take a look at the BigInt implementation on Code Project. Even if they don't have a function to convert to hex, you could easily write a function to do it yourself as long as this BigInt has a divide and modulo operation (I don't think it has a modulo function, so you would also need to write modulo yourself)

smoore
A: 

You could also try to disassemble (for example with reflector) BigInteger structure of .Net 4 implementation and copy methods you need (probably internally it uses 3.5 compatible code)

digEmAll
+7  A: 

Oh, that's easy:

        var s = "843370923007003347112437570992242323";
        var result = new List<byte>();
        result.Add( 0 );
        foreach ( char c in s )
        {
            int val = (int)( c - '0' );
            for ( int i = 0 ; i < result.Count ; i++ )
            {
                int digit = result[i] * 10 + val;
                result[i] = (byte)( digit & 0x0F );
                val = digit >> 4;
            }
            if ( val != 0 )
                result.Add( (byte)val );
        }

        var hex = "";
        foreach ( byte b in result )
            hex = "0123456789ABCDEF"[ b ] + hex;
danbystrom
yes, this is indeed a very nice solution, and when aiming for performance this is a better place to start than creating a BigInteger object. But for maintainability, this increases the code size and the complexity. So I would only go down this road if you use it in a very tight loop or some sort of core message handler. But still +1 for providing the loop based conversion.
Davy Landman
It's a stepping stone. For performance, you would obviuosly not use a List<byte>, but a sufficiently big byte[]. When you have done that, it *will* be *fast*.
danbystrom
yes, there are multiple ways, you could pre estimate the maximum width of the array, and use a char array directly, and just consume the digits needed. than you could just create a string from the correct subset of that result array.
Davy Landman
beautiful solution
msarchet
Have you profiled it whether it is faster than the straightforward implementation using BigInteger? To me result just look like a poor man's implementation of a big integer.
starblue