È un bug di Matlab? Hai lo stesso problema?

La mia versione di Matlab è R2012a
Perché in Matlab 1.1-0.2 non è uguale a 0.9 !!!!!?
Questo è terribile!

>> 1.1-0.2 == 0.9

ans =

0 

Non è un problema di Matlab; è un problema in virgola mobile. Otterrai lo stesso risultato in C ++ (o qualsiasi linguaggio di programmazione conforms allo standard IEEE754 ):

 #include  int main(int, char **) { std::cout << (1.1-0.2==0.9) << std::endl; return 0; } 

produzione:

 0 

Questo perché 1.1 e 0.9 non possono essere rappresentati esattamente in binario . È come esprimere 1/3 in decimale: dovrai scrivere

 0.33333333333333333333333333333333333333333333333... 

e continuare all'infinito. Ma non importa quanto tu continui, non riuscirai mai a farlo bene.

In virgola mobile, hai solo così tante cifre che puoi memorizzare, quindi il calcolo dovrà fermarsi da qualche parte. Il risultato del calcolo è in realtà

 >> 1.1-0.2 ans = 9.000000000000001e-01 

che è abbastanza vicino, ma non del tutto corretto.

Per questo motivo, dovresti sempre pensarci due volte prima di usare == per confrontare due numeri in virgola mobile; è raro che l'operatore == possa essere applicato senza alcune "strane" conseguenze come quella che hai appena incontrato.

È meglio usare una tolleranza specifica round-off, come

 abs(1.1-0.2 - 0.9) <= eps(0.9) 

dove eps è una funzione di Matlab che restituisce la spaziatura tra i doppi per uno specifico valore doppio. Ma in realtà, questa non è una soluzione per tutti. il corretto confronto tra i punti fluttuanti è un affare complicato.

http://matlab.wikia.com/wiki/FAQ#Why_is_0.3-0.2-0.1_not_equal_to_zero_.28or_similar.29.3F

Scorrere fino a “Perché 0.3 – 0.2 – 0.1 (o simile) non è uguale a zero?”

“Alcuni numeri in virgola mobile non possono essere rappresentati esattamente in formato binario …. Se stai cercando di confrontare due numeri in virgola mobile, stai molto attento a usare == per farlo. Un metodo di confronto alternativo è per verificare se il due numeri che stai confrontando sono “abbastanza vicini” ”

Una buona funzione da usare per questo genere di cose per vedere cosa sta succedendo è num2strexact dallo scambio di file

 num2strexact(1.1-0.2) 0.9000000000000001332267629550187848508358001708984375 num2strexact(0.9) 0.90000000000000002220446049250313080847263336181640625 

Vedi, non sono la stessa cosa.

Guarda le diverse quando si utilizza il doppio vs syms

 num2strexact((1.1-0.2)-0.9) 1.1102230246251565404236316680908203125e-16 sym('(1.1-0.2)-0.9') 1.8367099231598242312011508394098e-40