Domanda

Ricevo uno strano problema durante l'analisi di un valore doppio nel C++ gestito.Può darsi che sto facendo qualcosa di sbagliato.Quando io faccio:

double value = 0.006;
result = Math::Parse( value)

L'output del risultato è 0.006000000000001.Perché viene aggiunto un 1?

Inoltre, quando arrotondo il valore a 5 cifre decimali, fallisce.Sto facendo:

result2 = Math::Round(result, 5)

Ma result2 è sempre 0.006000000000001.Che cosa sto facendo di sbagliato?

È stato utile?

Soluzione

È normale.Questo problema causato dal formato IEEE di double - in real 0,006 è rappresentato come approssimazione della frazione binaria infinita.Quindi hai 3 modi:

  • utilizzare la formattazione della stringa corrispondente all'output
  • utilizzare il tipo decimale
  • non usare == per confrontare i numeri, usa invece < o > con errore costante, ad esempio:(X -0,06) < Errore

Altri suggerimenti

Ciò è dovuto alla precisione. Ho dato questa risposta qui :

  

float e double sono certo numero   rappresentazioni con un certo   precisione. Non ogni valore può essere   rappresentato in questo formato. Vedere    qui pure.

     

Si può facilmente pensare perché questo sarebbe   essere il caso: c'è un illimitato   numero di serie solo nella Intervallo   (1..1), ma un galleggiante ha solo una limitata   numero di bit per rappresentare tutti   numeri (-MAXFLOAT..MAXFLOAT).

     

Più giustamente messo: in un numero intero a 32 bit   rappresentazione c'è una numerabile   numero di interi da rappresentare,   Ma v'è un infinito innumerevole   numero di valori reali che non possono essere   pienamente rappresentati in una limitata   rappresentazione di 32 o 64 bit.   Quindi non solo v'è un limite alla   il più alto e quello più basso rappresentabili   valore reale, ma anche per la precisione.

     

Quindi, perché è un numero che ha poco   cifre dopo la virgola mobile   colpiti? Poiché la rappresentazione   si basa su un sistema binario anziché   un decimale, rendendo altri numeri facilmente   rappresentato poi quelle decimali.

Numeri doppia precisione sono essenzialmente approssimazioni, e hanno spesso code che si non può sbarazzarsi di -. Vale a dire non v'è alcun modo di esprimere il numero più accuratamente

Si potrebbe ottenere risultati più come ci si aspetta se si utilizza decimal - che è ancora un'approssimazione, ma utilizza in base 10, in modo tende a comportarsi più come la gente si aspetta. Ma perché non la mappa a un tipo di CPU, è più lento.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top