Sto cercando di convertire una stringa in un float senza perdita di dati, ad esempio se uso istringstream o :: atof (x.c_str ()) perdo dati a causa dell'arrotondamento.
Normalmente questo non è un problema per me, ma sto usando dati che devono essere uguali a quelli letti. Ecco un esempio di un numero e di ciò a cui è stato convertito.
-8.000001 -> -8
-0.6257381 -> -0.625738
12.0 -> 12 (drops the .0)
Se qualcuno potesse darmi una mano, sarei molto grato
Grazie Matt
risposte:
4 per risposta № 1Ci sono tre potenziali problemi nella tua domanda:
La quantità di precisione visualizzata. Per controllare la precisione usata, includi
#include <iomanip>
e usarestd::cout << std::setprecision(17);
per impostare il numero di cifre da utilizzare.Formattazione. Nel caso di volere "12.0" per "12.0", si dovrebbe essere consapevoli che ".0" non è memorizzato in un
float
odouble
. Ildouble
contiene solo il valore 12; non contienequalsiasi informazione sulla precisione originale o un intervallo di errore. Sono esattamente 12 e nient'altro. Se si desidera formattarlo in un modo particolare, è necessario utilizzare i flag di formato per lo stream I / O o scrivere il proprio codice per eseguire la formattazione.Precisione. Il comune
float
edouble
i tipi non possono rappresentare esattamente 8.000001 o 0.6257381. Usano il binario per rappresentare i valori in virgola mobile e ci saranno lievi errori quando i numeri decimali vengono convertiti in binari. Se hai un uso molto semplice di floating-point e lavori con cifre significativamente inferiori rispetto ai limiti difloat
edouble
, quindi potresti essere in grado di ignorarlo e semplicemente formattare i numeri con il tuo numero limitato di cifre. Se superi i casi semplici, dovresti fare un'analisi degli errori, che può essere piuttosto complicata.
1 per risposta № 2
Avrai bisogno di un tipo di dati diverso.
Un tipo decimale a virgola mobile consente dimemorizzare il numero esattamente come desiderato. In tale tipo, i numeri vengono memorizzati come una coppia (mantissa, esponente) proprio come la notazione scientifica e molto simile al punto in virgola mobile IEEE.
I tuoi esempi verrebbero archiviati come
(-8000001, -6)
(-6257381, -7)
(120, -1)
Ad esempio, lo standard ISO 11073 per le comunicazioni con dispositivi medici utilizza tale formato.
Lo svantaggio è che l'aritmetica sarà piuttosto lenta, dal momento che tutto l'hardware aritmetico a virgola mobile è progettato per funzionare con il numero usando un esponente con base-2.
0 per risposta № 3
Come regola generale, a float
è solo preciso a 6 cifre significative. Quindi se la tua stringa ha più cifre in quanto tu raggiungerai il limite di precisione.
UN double
ti darò, non a caso, di raddoppiare questa precisione; cioè 12 cifre significative.
Vedere Numero di cifre significative per un tipo a virgola mobile per ulteriori osservazioni.