2012-09-14 8 views
5

Sembra che ci sia un qualche tipo di errore di arrotondamento oscura quando si esegue il seguente codice:Risultato della fusione doppia in int è sbagliato

int roundedTotal = (int)(PriorityJob * 100.0); 

Inizialmente PriorityJob = 1.4 e roundedTotal non è definito. La valutazione di PriorityJob * 100.0 a quel punto fornisce 140. Successivamente roundedTotal = 139.

Apparentemente 140.0 viene interpretato come 139.99999. Si tratta di una carenza nel motore a virgola mobile? Non ho mai visto nulla di simile.

+1

non hai mai visto approssimati? –

+4

1.4 non esiste come float. Infatti, c'è un numero infinito di numeri anche tra 1.0 e 2.0 che non possono essere rappresentati come float, 1.4 è uno di questi. Quindi viene memorizzato come un'approssimazione di 1.4, come 1.3999999999999999 – nos

+0

@LuchianGrigore Sembra un'operazione così semplice. Perché dovrebbe fallire così? –

risposta

10

Quasi tutti i computer moderni utilizzano un numero binary representation per numeri in virgola mobile.

Come 1/3 = 0.33333333... non possono essere rappresentati esattamente come frazione decimale, così 1/10 (e quindi valori decimali non interi più, tra 1.4) non possono essere rappresentati esattamente come frazione binaria. Sarà invece rappresentato dal valore rappresentativo più vicino, che può essere leggermente più o meno del valore "vero".

Si potrebbe voler arrotondare all'intero più vicino, invece: (int)(PriorityJob * 100.0 + 0.5) numeri float

+1

E la differenza nei valori visualizzati si presenta perché 'std :: cout << PriorityJob * 100.0' rounds, mentre' int roundTotal = PriorityJob * 100.0' fa cadere la parte frazionaria. –

Problemi correlati