Libreria ad alta precisione Java floating point

Quali librerie per Java esistono con un’implementazione rapida per operazioni in virgola mobile o in virgola fissa con una precisione di diverse migliaia di cifre? Quanto sono performanti?

Un requisito per me è che implementa un algoritmo di moltiplicazione che è migliore dell’algoritmo di moltiplicazione naive che richiede 4 volte più tempo per un numero di cifre 2 volte maggiore (confronta gli algoritmi di moltiplicazione ).

Ci sono tre librerie menzionate nella pagina Aritmetica di precisione arbitraria : java.math (che contiene il citato BigDecimal), Apfloat e JScience . Corro un piccolo controllo della velocità su di loro che utilizza solo addizione e moltiplicazione.

Il risultato è che per un numero relativamente piccolo di cifre, BigDecimal è OK (la metà è veloce quanto gli altri per 1000 cifre), ma se si utilizzano più cifre è molto lontano – JScience è circa 4 volte più veloce. Ma il chiaro vincitore delle prestazioni è Apfloat. Le altre librerie sembrano utilizzare algoritmi di moltiplicazione ingenui che richiedono tempo proporzionale al quadrato del numero di cifre, ma il tempo di Apfloat sembra crescere in modo quasi lineare. Su 10000 cifre era 4 volte più veloce di JScience, ma su 40000 cifre è 16 volte più veloce di JScience.

D’altra parte: JScience fornisce funzionalità ECCELLENTE per problemi matematici: matrici, vettori, algoritmi simbolici, soluzione di sistemi di equazioni e cosa no. Quindi probabilmente andrò con JScience e poi scriverò un wrapper per integrare Apfloat negli algoritmi di JScience – a causa del buon design questo sembra facilmente ansible.

(AGGIORNAMENTO: Ho scritto una suite di test per il pacchetto di numeri di JScience e corretto un numero di bug. Questo è entrato nella versione 4.3.1. Quindi posso consigliarti di verificarlo.)

Hai controllato le prestazioni di BigDecimal ? Non riesco a vedere nulla di ovvio nel JavaDoc, ma sarebbe sicuramente il mio primo punto di riferimento.

Puoi dare un’occhiata alla libreria di JScience e alla loro class di numeri reali . Non sono sicuro di come le prestazioni siano relative a BigDecimal, ma l’objective della libreria è fornire classi altamente sintonizzate per applicazioni scientifiche, il che sembra un buon segno.

Apfloat offre un’elevata precisione sulla mantissa, ma sembra dare una precisione inferiore all’usuale sull’esponente (in base al fatto che si blocca con “Logaritmo di zero” per i valori che possono gestire due volte). Quindi non è utile per i grandi numeri.

Inoltre, la documentazione dice:

“Esiste un trabocchetto con i costruttori Apfloat (float, long) e Apfloat (double, long) .Dal momento che float e double sono sempre rappresentati internamente in radix 2, la conversione a qualsiasi altro radix normalmente causa errori di arrotondamento, e il conseguente apfloat non sarà preciso al numero desiderato di cifre.

Ad esempio, 0.3 non può essere presentato esattamente nella base 2. Quando si costruisce un apfloat come nuovo Apfloat (0.3f, 1000), il numero risultante non sarà preciso a 1000 cifre, ma solo a circa 7 cifre (in radix 10). In effetti, il numero risultante sarà qualcosa come 0.30000001192092896 … ”

Questo sembra rendere Apfloat minimamente utile.

BigDecimal non ha una funzione logaritmo e la documentazione non dice se ti permette di fare numeri più grandi di un doppio; l’esponente è a 32 bit, una specie di.