17


1

(文字列形式の)gi-normous整数を16進形式に変換する方法は? (C#)

潜在的に巨大な整数値(C#文字列形式)が与えられた場合、その16進数に相当するものを生成できるようにしたいと思います。 50桁以上の任意の大きな数字を話しているため、ここでは通常の方法は適用されません。 このようなテクニックを使用する私が見たテクニック:

// 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);

変換する整数が大きすぎるため機能しません。

たとえば、次のような文字列を変換できる必要があります。

843370923007003347112437570992242323

その16進数に相当します。

これらは機能しません:

C#整数を16進数に変換してから元に戻す https://stackoverflow.com/questions/74148/how -to-convert-numbers-between-hex-and-decimal-in-c [C#で16進数と10進数の間で数値を変換する方法?]

4 Answer


22


ああ、それは簡単です。

        var s = "843370923007003347112437570992242323";
        var result = new List();
        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;


7


BigIntegerを使用して整数を保存し、http://msdn.microsoft.com/en-us/library/dd268260を使用しますそのオブジェクトの.aspx [.ToString( "X")]。

例:

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

ただし、これは.NET 4以降に制限されています。 しかし、イェンスA. codeprojectのBigIntegerクラスを指し、そのクラスには、<.NET 4シナリオで機能する `ToHexString`というメソッドが含まれています。


2


Jensが言ったように、http://www.codeproject.com/KB/cs/BigInt.aspx?msg = 3042180 [Code Project]のBigInt実装を見てください。 16進数に変換する機能がない場合でも、このBigIntに境界線があり、自分で行うには、http://en.wikipedia.org/wiki/Hexadecimal#Converting_from_other_bases [関数を書く]モジュロ演算(モジュロ関数があるとは思わないので、http://en.wikipedia.org/wiki/Modulo_operation#Remainder_calculation_for_the_modulo_operation [modulo]を自分で記述する必要もあります)


1


これまでの12月の<→ hex変換のための素晴らしいソリューションは、これまでのstackoverflowで、…​ しかし、私は(巨大なintを必要としました。 巨大な部分)精度がほとんど失われないため、すでに完了したコードで見つかったすべてのコードを変更し、ここで共有できるものがあります(大きなint /実際のlibの使用なしで)

//---------------------------------------------------------------------------
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='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. 小数桁を切り捨てる必要がある場合(数値をフォーマットするため)、切り取られた部分の最上位桁で丸める必要があります。

  • 桁> = '5’の場合、decモードでabsを切り上げます

  • 桁> = '8’の場合、16進モードでabsを切り上げます

この行が何を意味するのか疑問に思う場合

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

入力文字列の精度と一致する小数桁数を計算します(16進小数桁ごとに1.205 10進小数桁)。 この比率は、数値の小数部分あたり最大1280ビットの精度の経験的測定によって得られます。 簡単にするために、1e-lは1e-(l + 1)までの最大誤差で保存できます。 この比率はほぼ一定です(小数桁の値(<16桁)を除く)。したがって、この式は、任意の大きな桁数に対して安全に使用できます。 低い入力桁値では、誤った最大1(> 8桁)または最大2(⇐ 8桁)桁で出力されます