2013-07-05 5 views
5
#include <iostream> 
using namespace std; 

int main() 
{ 
    cout.precision(32); 

    float val = 268433072; 
    float add = 13.5; 

    cout << "result =" << (val + add) << endl; 
} 

Sto compilando il programma di cui sopra alla norma g++ main.cc
e funzionante con ./a.outStrano C++ float bug

L'ouput che ricevo è però,
result =268433088

Chiaramente, questo è non è la risposta corretta. Perché sta succedendo?

EDIT: Questo non si verifica quando si utilizza double al posto di float

+9

Si potrebbe desiderare di leggere [Ciò che ogni scienziato informatico dovrebbe sapere sull'aritmetica virgola mobile] (http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html). –

+0

Un'altra buona lettura sui problemi in virgola mobile: http://stackoverflow.com/questions/1089018/why-cant-decimal-numbers-be-represented-exactly-in-binary – mtrw

+3

Che comportamento ti aspetti invece? (Voglio dire, dal fatto che hai provato sia 'float' che' double', ovviamente ti rendi conto che 'float' ha una precisione limitata ...) – ruakh

risposta

8

È possibile riprodurre la vostra "float bug" con un pezzo ancora più semplice del codice

#include <iostream> 
using namespace std; 

int main() 
{ 
    cout.precision(32); 
    float val = 2684330722; 
    cout << "result =" << val << endl; 
} 

L'uscita

result =2684330752 

Come si può vedere l'uscita non corrisponde al valore val è stato inizializzato con.

Come è stato affermato più volte, i tipi a virgola mobile hanno una precisione limitata. Il tuo codice ha semplicemente superato la precisione, quindi il risultato è stato arrotondato. Non c'è "bug" qui.

+0

Chi ha downvoted questo e perché? – Borgleader

1

parte il riferimento (1991, PDF) What Every Computer Scientist Should Know About Floating-Point Arithmetic

La risposta breve è, perché galleggiante trovi limitata stoccaggio (come le altre primitive anche) gli ingegneri dovuto fare una scelta: quali numeri memorizzare con cui precisione. Per i formati in virgola mobile hanno deciso di memorizzare numeri di di piccola magnitudine con precisione (alcune cifre decimali), ma i numeri di di grande ampiezza in modo molto impreciso, infatti a partire da + -16.777,217 i numeri rappresentabili stanno diventando così sottili che tutti gli interi sono rappresentati che è la cosa che hai notato.