Problema in double.Parse in Managed C++
-
11-09-2019 - |
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?
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.