2010-11-05 19 views
5

Sto scrivendo una funzione che calcola il valore di PI e lo restituisce come un doppio. Fin qui tutto bene. Ma una volta che la funzione raggiunge le 14 cifre dopo la cifra decimale, non può più trattenerla. Suppongo che questo sia dovuto alla precisione limitata del doppio. Cosa devo fare per continuare a ottenere più numeri dopo la cifra decimale?C# Alta precisione doppia

risposta

16

Non lo farei mai in virgola mobile.

Ricordiamo che il vostro algoritmo è:

(1 + 1/(2 * 1 + 1)) * 
(1 + 2/(2 * 2 + 1)) * 
(1 + 3/(2 * 3 + 1)) * 
(1 + 4/(2 * 4 + 1)) * 
(1 + 5/(2 * 5 + 1)) * 
(1 + 6/(2 * 6 + 1)) * 
(1 + 7/(2 * 7 + 1)) * ... 

Ogni fase lungo la strada di calcolare una frazione. Perché non mantenere semplicemente quella frazione nella sua forma di numeratore/denominatore? La frazione si vuole calcolare è:

(4/3) * 
(7/5) * 
(10/7) * 
(13/9) * ... 

che è a soli 4 * 7 * 10 * 13 ... sulla parte superiore e 3 * 5 * 7 * 9 sul fondo.

Ottieni te stesso una classe BigInteger (una viene fornita con il framework 4.0 in System.Numerics) e puoi facilmente calcolare il numeratore e il denominatore grande quanto vuoi. Quindi hai solo il problema di convertire il quoziente in decimale. Bene, è abbastanza facile. Presumibilmente sai come fare la divisione lunga. Basta implementare un algoritmo di divisione lunga sul numeratore e denominatore che sputa il numero desiderato di cifre.

8

Di quanto precisione hai bisogno?

Utilizzando decimal vi darà circa 28 cifre decimali:

decimal pi = 3.14159265358979323846264338327950288419716939937510m; 
Console.WriteLine(pi); // 3.1415926535897932384626433833 

Se questo non è abbastanza per voi, allora avrete bisogno di cercare un qualche tipo di implementazione BigDecimal, o guardare altre tecniche per eseguire il calcolo .

0

Sì, è perché la precisione limitata del doppio. Esistono diversi modi per calcolare le cifre di pi. Suggerirei di chiedere al tuo motore di ricerca preferito, "come calcolare le cifre di pi".

0

È possibile utilizzare il tipo J # BigDecimal, come suggerito in this answer.

1

Esistono diverse librerie che consentono di lavorare con precisione arbitraria. Uno è W3b.sine, ma molti altri sono descritti su wikipedia.

1

Prova decimal anziché doppio. Non è possibile memorizzare numeri grandi come il doppio, ma penso che abbia una maggiore precisione dopo il decimale. Se hai bisogno di più, probabilmente dovrai usare una stringa.

+0

Non vorrei usare una stringa - avresti un sovraccarico extra di conversione in/da numeri. – JLWarlow

+0

Sì, ma se hai bisogno di più di er, precisione a 28 cifre, non ci sono tipi di dati incorporati per questo. IIRC C# ha un qualche tipo di classe per i valori con (praticamente) la dimensione illimitata, e sono abbastanza sicuro che li memorizzerebbe internamente come una stringa ... – user472875

+0

... o un array di byte. –

Problemi correlati