简体   繁体   English

如何将一个巨大的整数(字符串格式)转换为十六进制格式? (C#)

[英]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. 给定一个潜在的巨大整数值(采用C#字符串格式),我希望能够生成其十六进制等效值。 Normal methods don't apply here as we are talking arbitrarily large numbers, 50 digits or more. 普通方法在这里不适用,因为我们正在谈论任意大数,50位或更多。 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 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#? C#将整数转换为十六进制再返回 如何在C#中转换十六进制和十进制之间的数字?

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;

Use a BigInteger to store the integer, and than use the .ToString("X") on that object. 使用BigInteger存储整数,然后使用该对象上的.ToString(“X”)

Example: 例:

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

This is however limited to .NET 4 and later. 但是,这仅限于.NET 4及更高版本。 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. 但是Jens A. 在codeproject上指向了一个BigInteger类 ,该类包含一个名为ToHexString的方法,因此适用于<.NET 4场景。

As Jens said, take a look at the BigInt implementation on Code Project . 正如Jens所说,看一下Code Project上的BigInt实现。 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) 即使它们没有转换为十六进制的函数 ,只要这个BigInt有一个除法和模运算,你就可以轻松地编写一个函数来自己做(我不认为它有模数函数,所以你会还需要自己写模数

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) 到目前为止,在stackoverflow上对dec < - >十六进制转换很好的解决方案,...但我需要(巨大的int。巨大的分数)几乎没有精度丢失所以我修改了我用我已经完成的代码找到的所有代码,这里是一些我可以分享(没有大的int / real 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<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;
    }
//---------------------------------------------------------------------------

PS 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' 如果数字> ='5',则以dec模式舍入abs
  • rounding abs up in hex mode if digit >='8' 如果数字> ='8',则以十六进制模式舍入abs

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). 而不是计算匹配输入字符串精度的小数位数(每个十六进制小数位1.205十进制小数位)。 This ratio i get by empirical measurement of accuracy up to 1280 bits per fractional part of number. 这个比率我通过经验测量精度得到每个小数部分的1280位。 for simplicity 1e-l can be stored with max error up to 1e-(l+1). 为简单起见,1e-l可以存储,最大误差可达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 该比率几乎是恒定的(低分数位值(<16位)除外)因此该公式可以安全地用于任何更大的数字。在低输入数字值输出错误最多1(> 8位)或最大2 (<= 8位)数字

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM