2012-07-05 7 views
8

Fino ad oggi, io (implicitamente) ho assunto che quando producevo un metodo di istanza senza parametro (sovrascritto) BigInteger.ToString(), la stringa di restituzione conterrebbe la rappresentazione decimale completa ed esatta del mio intero "grande".In .NET, la stringa restituita da BigInteger.ToString() riflette la precisione completa di BigInteger?

Ma the MSDN doc page ho letto:.

"Nella maggior parte dei casi, il metodo ToString supporta 50 cifre decimali di precisione Cioè, se il valore BigInteger ha più di 50 cifre, solo la 50 cifre più significative vengono mantenute nella stringa di output, tutte le altre cifre vengono sostituite con zeri.Tuttavia, BigInteger supporta lo specificatore di formato standard "R", che è destinato ai valori numerici di andata e ritorno. ToString (String) metodo con l' stringa di formato "R" conserva tutta BigInteger valore e può quindi essere analizzato con il TryParse metodo Parse o per ripristinare il valore originale senza alcuna perdita di dati". _

Tuttavia, non sono stato in grado di trovare un esempio in cui myBigInt.ToString() differisce da myBigInt.ToString("R"). L'esempio Remarks della pagina precedente non fornisce, come affermato, un esempio, nella mia versione del framework (.NET 4.0 SP1). (Anche "G" e "R" sembra essere equivalente per BigInteger.)

E 'lecito ritenere che il paramterless ToString() dà l'espansione decimale pieno di numero intero? Hanno cambiato il comportamento del framework o il codice di esempio sopra menzionato è sempre stato errato?

Nota: mi mostra SO this "similar question" 2984184 dopo che ho scritto questo, ma io sono ancora presentando la mia domanda, perché la risposta di 2.984.184 realtà non claryfy come i parametri zero ToString() opere.

EDIT BY MYSELF:

E 'stato un po' di me incosequent per collegare la ToString(String) sovraccarico su MSDN, quando la mia domanda è (soprattutto) sulla ToString() sovraccarico. Quindi vedi anche MSDN on BigInteger.ToString() che menziona il limite di 50 cifre, ma non fornisce un esempio con più di 50 cifre.

risposta

4

Decompilazione di .NET 4.0 framework dà questa catena di chiamate:

BigInteger.ToString 
BigNumber.FormatBigInteger(... format:= null ...) 
BigNumber.ParseFormatSpecifier(format ...) 

entro cui abbiamo

if (string.IsNullOrEmpty(format)) 
    return 'R'; 

così si può vedere che in questa implementazione , ToString() è equivalente a ToString("R"). Ma, as pointed out by @PaulPhillips, dato che i documenti (leggermente confusamente) negano esplicitamente l'affidabilità di questo, direi che la cosa più sicura (e comunque la più autodocumentante) da fare è usare "R" quando hai bisogno di piena fedeltà .

+1

"così si può vedere che in questa implementazione, ToString() è equivalente a ToString (" R ")" - Vale la pena ricordare: ciò non smentisce la promessa dei documenti che ToString() è equivalente a ToString ("G "): è ancora vero se ToString (" G ") e ToString (" R ") hanno lo stesso effetto. – hvd

+0

.net 3.5 ha la propria implementazione di ToString. Quindi questo potrebbe essere nuovo a .net 4.0. In realtà, non c'è nemmeno una classe BigNumber in 3.5. – hatchet

+0

Nevermind - BigNumber non è pubblico in 3.5 (è interno). Mi chiedo se si tratti di una documentazione di questa precedente implementazione interna. – hatchet

3

Non penso che sia un'ipotesi sicura.

Dal momento che lo hanno esplicitamente documentato come non, sembra una cattiva idea affidarsi a questo comportamento. Se in realtà è lo stesso, quindi non documentato e potrebbe teoricamente cambiare in qualsiasi momento (anche se questo sembra improbabile).

+0

In ogni caso, la documentazione è errata (l'implementazione corrente), e l'esempio nella sezione "Note" nella pagina sul sovraccarico 'ToString (String)' non ** produce ** l'output claim: il formato '" G "' non perde informazioni (nel loro esempio). –

0

Guardando il codice sorgente del metodo ToString() chiama semplicemente:

BigNumber.FormatBigInteger(this, (string)null, NumberFormatInfo.CurrentInfo);

Da lì, il metodo interno BigNumber.FormatBigInteger(BigInteger value, string format, NumberFormatInfo info) ha la seguente logica:

int digits = 0; 
char format1 = BigNumber.ParseFormatSpecifier(format, out digits); 

Così, ora guardiamo la Metodo BigNumber.ParseFormatSpecifier(string format, out int digits) e scoprire che, poiché è passato in una stringa nulla, restituisce semplicemente il carattere 'R' con il numero numero di cifre (digits) uguale a -1. Considerando che, se si è effettivamente passati in un formato stringa, è possibile specificare anche il numero di cifre, ad esempio ... 'R25' e analizzerà 25 come numero di cifre.

Questo è ciò che ho capito guardando il codice sorgente.

+0

Sembra che i pad "" R25 "' con zeri ** prima ** il numero se il numero ha meno di 25 cifre in primo luogo. Quando il numero ha, per esempio, 1000 cifre, sembra che "R" e "R25" producano lo stesso risultato e non vengano aggiunti zeri e in questo caso le cifre non vengono sostituite con zeri. –