Come usare PrintF con MPFR e MPREAL
Domanda
Qual è la sintassi corretta per l'utilizzo di printf
e dei suoi cugoni sprintf
e fprintf
per visualizzare il valore delle variabili di tipo mpreal
?Ho provato la casting ingenua da raddoppiare:
printf ("... %g ...", (double) var);
.
Solo per ricevere questo messaggio di errore da G ++:
error: invalid cast from type ‘mpfr::mpreal’ to type ‘double’
.
Non ho avuto problemi a utilizzare le variabili di tipo double
altrove sul programma.
Ho sentito del tipo mpreal
come parte di questo Libreria destinata a abilitare l'uso diI soliti operatori binari per eseguire operazioni aritmetiche di precisione arbitrarie.
Soluzione
Il mpreal
è il tipo numerico del punto flottante di precisione arbitrario.
In quanto tali, i numeri mpreal
potrebbero avere cifre molto più significative (anche centinaia o millesime) rispetto a double
. Il che significa che è inutile a round mpreal
a double
prima del display - perderai tutta la precisione originale in questo caso.
È facile visualizzare mpreal
in C ++:
.
/* 100-digits accurate pi */
mpreal pi = mpfr::const_pi(mpfr::digits2bits(100));
/* Show 60-digits of pi */
cout.precision(60);
cout << pi;
Tuttavia è possibile utilizzarlo anche con printf
(convertendo in stringa prima):
.
/* Display all digits (default formatting) */
printf("pi = %s\n", pi.toString().c_str());
/* Custom format, 60 digits */
printf("pi = %s\n", pi.toString("%.60RNf").c_str());
/* Using native printf from MPFR*/
mpfr_printf("pi = %.60RNf\n", pi.mpfr_srcptr());
Formato Specifiche per numeri di precisione multipli sono gli stessi di standard con l'eccezione alle specifiche di arrotondamento. È possibile utilizzare tranquillamente l'arrotondamento su più vicino, RN
come negli esempi sopra.
Maggiori dettagli su MP-Formattazione sono riportati in Documentazione MPFR . (Io sono autore di mpreal
Class Aka MPFR C ++ )
Altri suggerimenti
mpreal
è una classe, non un tipo numerico e non fornisce operatori di conversione a tipi numerici.
Ma fornisce funzioni associate che eseguono conversioni di tipo:
long toLong() const;
unsigned long toULong() const;
double toDouble() const;
long double toLDouble() const;
.
Quindi questo dovrebbe funzionare:
printf ("... %g ...", var.toDouble());
.
o:
printf ("... %Lg ...", var.toLDouble());
.
(Non l'ho confermato.)
Aggiornamento:
Un oggetto mpreal
rappresenta un numero reale che può avere una gamma molto maggiore e / o una precisione di quanto possa essere rappresentato da qualsiasi tipo numerico incorporato (questo è l'intero punto di MPFR).La conversione in un tipo numerico ha senso solo se il valore è compreso tra l'intervallo di quel tipo, e non ti importa della precisione extra.
In alcuni casi, potrebbe essere abbastanza buono, ma come questa risposta dice, è possibile stampare la piena precisione usandoOperatore <<
sovraccarico o funzione membro di toString()
.