Qual è l'equivalente della classe Java BigDecimal in C #?
-
30-09-2019 - |
Domanda
BigDecimal
è una classe nel pacchetto java.math
che ha un sacco di benefici per la gestione di grandi numeri di una certa importanza. C'è una classe o di dati di tipo equivalente in C # con questa caratteristica.
Soluzione
C # solo ha BigInteger
costruito (in .NET Framework 4).
È decimal
sufficiente precisione per il vostro compito? E 'un numero di 128 bit che può contenere valori nel campo ± 1,0 x 10 -28 a ± 7.9 × 10 28 .
Altri suggerimenti
Proprio di recente ho anche bisogno di un decimale di precisione arbitraria in C # e mi sono imbattuto l'idea postato qui: https://stackoverflow.com/ un / 4524254/804614
Ho poi completato il progetto per supportare tutti gli operatori aritmetici e confronto di base, nonché le conversioni da e per tutti i tipi numerici tipici e alcuni metodi esponenziali che mi serviva in quel momento.
Certamente non è completo, ma molto funzionale e quasi pronto per l'uso. Dato che questo è il risultato di codifica una notte, non vi posso assicurare che questa cosa è privo di bug o del tutto esatto, ma ha funzionato grande per me. Ad ogni modo, voglio pubblicarlo qui perché non ho trovato altro modo per usare i decimali a precisione arbitraria in C #, senza la necessità di includere massicce librarys (per lo più nemmeno .net, ma wrapper C ++), che vengono con tutti i tipi di inutili roba.
L'idea di base è quella di costruire tipo in virgola mobile un costume con un arbitrario grande mantissa utilizzando il tipo BigInteger di .NET 4.0 e una base di 10 esponente (Int32).
Se trovate bug / imprecisioni, hanno suggerimenti o qualcosa di costruttivo, non esitate a modificare direttamente il mio post o lasciare un commento così che io possa migliorare la risposta.
Io non sono del tutto sicuro se questo è il posto migliore per mettere questa cosa, ma questa è una delle domande più frequenti su così su questo argomento e ho davvero voglia di condividere la mia soluzione. ;)
EDIT: mi sono trasferito l'attuazione di GitHubGist: https://gist.github.com/JcBernack/0b4eef59ca97ee931a2f45542b9ff06d
Beh, a parte utilizzando librerie di terze parti con il supporto del BigDecimal (se esistono), non ci sono soluzioni alternative facili. Il modo più semplice, per quanto mi riguarda è di prendere un'implementazione decimale (da mono per esempio) e riscrivere utilizzando il tipo BigInteger. Internamente, in attuazione di mono, di tipo decimale è composto da tre numeri interi. Quindi non credo che sarebbe difficile da attuare. Non sono sicuro di efficienza però. Si dovrebbe prima però considerare l'utilizzo di tipo decimale standard, come codeka menzionato.
C'è una libreria C # chiamato bignum che fa quello che stai cercando, e in alcuni casi ha funzionalità aggiuntive.
Per esempio, ha una funzione di radice quadrata, che BigDecimal non ha:
PrecisionSpec precision = new PrecisionSpec(1024, PrecisionSpec.BaseType.BIN);
BigFloat bf = new BigFloat(13, precision);
bf.Sqrt();
Console.WriteLine(bf.ToString());
Wikipedia ha una lista di altri tali librerie a http: //en.wikipedia. org / wiki / arbitrario-precision_arithmetic # biblioteche
Fonti:
- La biblioteca bignum è stato originariamente ospitata presso http: //www.fractal-landscapes. co.uk/bigint.html , ma che il sito è stato giù dal 2012.
- È possibile trovare un archivio del sito all'indirizzo http://web.archive.org/web/20110721173046/http://www.fractal-landscapes.co.uk/bigint.html .
- C'è una copia del codice sorgente a http: //www.mediafire .com / file / 6axoicc6iszp4sg / BigNum.zip / il file
Questo non può essere stato un opzione quando la questione è stata originariamente pubblicato, ma in un modo davvero facile da usare un BigDecimal
nel codice C # è quello di installare il IKVM.NET tramite NuGet:
PM> Install-Package IKVM
Quindi fare esattamente come si farebbe in Java:
using System;
using java.math;
namespace BigDecimalDemo
{
class Program
{
static void Main(string[] args)
{
int n = int.Parse(args[0]);
Console.WriteLine(Factorial(n));
}
static BigDecimal Factorial(int n)
{
return n == 1
? BigDecimal.ONE
: Factorial(n - 1).multiply(new BigDecimal(n));
}
}
}
A seconda di quanto si va con IKVM non ci può essere il problema di interoperabilità occasionale a inciampare attraverso ma nella mia esperienza di solito funziona grande per cose semplici come questo.
Deveel Math
GitHub:
https://github.com/deveel/deveel-math
Autore GitHub:
Supporto:
- BigComplex
- BigDecimal
- BigMath
- razionale
- ...
Come installare It
Dalla console di NuGet gestione dei pacchetti, selezionare il progetto in cui verrà installato la biblioteca e digitare il seguente comando
PM> Install-Package dmath
È inoltre possibile utilizzare il Math.Gmp.Native package NuGet che ho scritto. Il suo codice sorgente è disponibile su GitHub , e la documentazione è disponibile qui . Espone a NET tutte le funzionalità della biblioteca GMP che è noto come altamente ottimizzato aritmetica precisione arbitraria biblioteca.
numeri a virgola mobile arbitraria precisione sono rappresentate dalla rel mpf_t tipo "nofollow noreferrer". Operazioni su questi numeri in virgola mobile tutti iniziano con il prefisso mpf_
. Per esempi, mpf_add o mpf_cmp . esempi di codice sorgente sono dati per ciascuna operazione.