'How to convert a gi-normous integer (in string format) to hex format? (C#)

Given a potentially huge integer value (in C# string format), I want to be able to generate its 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 its hex equivalent.

these don't work:

C# convert integer to hex and back again How to convert numbers between hexadecimal and decimal in C#?



Solution 1:[1]

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;

Solution 2:[2]

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.

Solution 3:[3]

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)

Solution 4:[4]

heh nice solutions for dec<->hex conversions here on stackoverflow so far ,... but i needed (gigantic int . gigantic fraction) with almost none precision lost so i modded all codes i found with my already done codes and here is some i can share (without big int/real lib usage)

//---------------------------------------------------------------------------
AnsiString str_hex2dec(const AnsiString &hex)
    {
    char c;
    AnsiString dec="",s;
    int i,j,l,ll,cy,val;
    int  i0,i1,i2,i3,sig;
    sig=+1; l=hex.Length();
    if (l) { c=hex[l]; if (c=='h') l--; if (c=='H') l--; }
    i0=0; i1=l; i2=0; i3=l;
    for (i=1;i<=l;i++)      // scan for parts of number
        {
        char c=hex[i];
        if (c=='-') sig=-sig;
        if ((c=='.')||(c==',')) i1=i-1;
        if ((c>='0')&&(c<='9')) { if (!i0) i0=i; if ((!i2)&&(i>i1)) i2=i; }
        if ((c>='A')&&(c<='F')) { if (!i0) i0=i; if ((!i2)&&(i>i1)) i2=i; }
        if ((c>='a')&&(c<='f')) { if (!i0) i0=i; if ((!i2)&&(i>i1)) i2=i; }
        }

    l=0; s=""; if (i0) for (i=i0;i<=i1;i++)
        {
        c=hex[i];
             if ((c>='0')&&(c<='9')) c-='0';
        else if ((c>='A')&&(c<='F')) c-='A'-10;
        else if ((c>='a')&&(c<='f')) c-='A'-10;
        for (cy=c,j=1;j<=l;j++)
            {
            val=(s[j]<<4)+cy;
            s[j]=val%10;
            cy  =val/10;
            }
        while (cy>0)
            {
            l++;
            s+=char(cy%10);
            cy/=10;
            }
        }
    if (s!="")
        {
        for (j=1;j<=l;j++) { c=s[j]; if (c<10) c+='0'; else c+='A'-10; s[j]=c; }
        for (i=l,j=1;j<i;j++,i--) { c=s[i]; s[i]=s[j]; s[j]=c; }
        dec+=s;
        }
    if (dec=="") dec="0";
    if (sig<0) dec="-"+dec;

    if (i2)
        {
        dec+='.';
        s=hex.SubString(i2,i3-i2+1);
        l=s.Length();
        for (i=1;i<=l;i++)
            {
            c=s[i];
                 if ((c>='0')&&(c<='9')) c-='0';
            else if ((c>='A')&&(c<='F')) c-='A'-10;
            else if ((c>='a')&&(c<='f')) c-='A'-10;
            s[i]=c;
            }
        ll=((l*1234)>>10);  // num of decimals to compute
        for (cy=0,i=1;i<=ll;i++)
            {
            for (cy=0,j=l;j>=1;j--)
                {
                val=s[j];
                val*=10;
                val+=cy;
                s[j]=val&15;
                cy=val>>4;
                }
            dec+=char(cy+'0');
            for (;;)
                {
                if (!l) break;;
                if (s[l]) break;
                l--;
                }
            if (!l) break;;
            }
        }

    return dec;
    }
//---------------------------------------------------------------------------
AnsiString str_dec2hex(AnsiString dec)
    {
    AnsiString hex=""; BYTE a,b;
    int  i,j,i0,i1,i2,i3,l,sig;
    sig=+1; l=dec.Length();
    i0=0; i1=l; i2=0; i3=l;
    for (i=1;i<=l;i++)      // scan for parts of number
        {
        char c=dec[i];
        if (c=='-') sig=-sig;
        if ((c=='.')||(c==',')) i1=i-1;
        if ((c>='0')&&(c<='9')) { if (!i0) i0=i; if ((!i2)&&(i>i1)) i2=i; }
        }
    if (i0) for (;i1>=i0;i1=j-1)// process integer part /16
        {
        for (a=0,j=i0,i=i0;i<=i1;i++)
            {
            a*=10; a+=dec[i]-'0';
            if (a<16) { if (j>i0){ dec[j]='0'; j++; } continue; }
            b=a>>4; a=a&15;
            if (b>10) { dec[j]='1'; j++; b-=10; }
            dec[j]=b+'0'; j++;
            }
        if ((!a)&&(hex=="")) continue;
        if (a<10) a+='0'; else a+='A'-10;
        hex=AnsiString(char(a))+hex;
        }
    if (hex=="") hex="0";

    if ((i2)&&(i2<=i3))     // process fractional part *16
     for (hex+=".",j=i3-i2+2;j;j--)
        {
        for (a=0,b=0,i=i3;i>=i2;i--)
            {
            a=dec[i]-'0';
            b+=a<<4; dec[i]=(b%10)+'0'; b/=10;
            }
        if (b<10) b+='0'; else b+='A'-10;
        hex+=char(b);
        }
    if (sig<0) hex="-"+hex; hex+="h";
    return hex;
    }
//---------------------------------------------------------------------------

P.S. if you need to cut off fractional digits (to format numbers) than you have to round by most significant digit of the cutted part.

  • rounding abs up in dec mode if digit >='5'
  • rounding abs up in hex mode if digit >='8'

if you wonder what means this line:

ll=((l*1234)>>10);  // num of decimals to compute

than it compute the number of fractional digits that match input string precision (1.205 decimal fractional digits per hexadecimal fractional digit). This ratio i get by empirical measurement of accuracy up to 1280 bits per fractional part of number. for simplicity 1e-l can be stored with max error up to 1e-(l+1). This ratio is almost constant (except for low fractional digit values (<16 digits) so this formula can be used for any larger num of digits safely. In low input digit values is output wrong max by 1 (>8 digits) or max 2 (<=8 digits) digits

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2
Solution 3 Seth Moore
Solution 4 Spektre