Come convertire un intero normale gi (in formato stringa) in formato esadecimale? (C #)

Dato un valore intero potenzialmente enorme (in formato stringa C #), voglio essere in grado di generare il suo equivalente esadecimale. I metodi normali non si applicano qui poiché stiamo parlando di numeri arbitrariamente grandi, 50 cifre o più. Le tecniche che ho visto che usano una tecnica come questa:

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

non funzionerà perché il numero intero da convertire è troppo grande.

Ad esempio, devo essere in grado di convertire una stringa come questa:

843370923007003347112437570992242323

al suo equivalente esadecimale.

questi non funzionano:

C # converte un numero intero in esadecimale e viceversa Come convertire i numeri tra esadecimale e decimale in C #?

Oh, è facile:

  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; 

Usa un BigInteger per memorizzare il numero intero e poi usa .ToString (“X”) su quell’object.

Esempio:

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

Questo è tuttavia limitato a .NET 4 e versioni successive. Ma Jens A. ha indicato una class BigInteger su codeproject che contiene un metodo chiamato ToHexString modo che funzioni per uno scenario .NET 4.

Come ha detto Jens, dai un’occhiata all’implementazione di BigInt su Code Project . Anche se non hanno una funzione per convertire in esadecimale, puoi facilmente scrivere una funzione per farlo da solo, purché questo BigInt abbia un’operazione di divisione e modulo (non penso che abbia una funzione modulo, quindi dovresti anche bisogno di scrivere modulo tu stesso)

heh belle soluzioni per dec < -> conversioni esadecimali qui su stackoverflow finora, … ma avevo bisogno (gigantesca int gigantesca frazione) con quasi nessuna precisione persa, quindi ho modificato tutti i codici che ho trovato con i miei codici già fatti ed ecco alcuni posso condividere (senza l’utilizzo di big 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='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 se è necessario tagliare le cifre frazionarie (per formattare i numeri) di quanto necessario per arrotondare la cifra più significativa della parte tagliata.

  • arrotondare abs in modalità dec se cifra> = '5'
  • arrotondare abs in modalità esadecimale se cifra> = '8'

se ti chiedi cosa significa questa linea:

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

di quanto calcoli il numero di cifre frazionarie che corrispondono alla precisione della stringa di input (1.205 cifre decimali decimali per cifra frazionaria esadecimale). Questo rapporto ottengo misurando empiricamente la precisione fino a 1280 bit per parte frazionaria del numero. per semplicità 1e-l può essere memorizzato con errore massimo fino a 1e (l + 1). Questo rapporto è quasi costante (eccetto per valori di cifre frazionarie basse (<16 cifre), quindi questa formula può essere utilizzata per un numero maggiore di cifre in modo sicuro. In valori di cifre di input bassi viene emesso un massimo errato di 1 (> 8 cifre) o massimo 2 (< = 8 cifre) cifre