/ / C ++ conversione della stringa in float / double senza perdita di dati - c ++, string, floating-point

Conversione in C ++ da stringa a float / double senza perdita di dati - c ++, string, floating-point

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 № 1

Ci sono tre potenziali problemi nella tua domanda:

  1. La quantità di precisione visualizzata. Per controllare la precisione usata, includi #include <iomanip> e usare std::cout << std::setprecision(17); per impostare il numero di cifre da utilizzare.

  2. Formattazione. Nel caso di volere "12.0" per "12.0", si dovrebbe essere consapevoli che ".0" non è memorizzato in un float o double. Il double 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.

  3. Precisione. Il comune float e double 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 di float e double, 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.