Sto vedendo qualcosa di strano con l'archiviazione dei doppi in un dizionario, e sono confuso sul perché.In che modo un C# valuta il punto mobile al passaggio del mouse sopra e finestra intermedia rispetto a compilato?
Ecco il codice:
Dictionary<string, double> a = new Dictionary<string, double>();
a.Add("a", 1e-3);
if (1.0 < a["a"] * 1e3)
Console.WriteLine("Wrong");
if (1.0 < 1e-3 * 1e3)
Console.WriteLine("Wrong");
La seconda istruzione if funziona come previsto; 1.0 non è inferiore a 1.0. Ora, la prima istruzione if viene valutata come vera. La cosa molto strana è che quando aleggi il puntatore del mouse sopra, l'intellisense mi dice che è falso, eppure il codice si sposta felicemente su Console.WriteLine.
Questo è per C# 3.5 in Visual Studio 2008.
È questo un punto problema precisione floating? Allora perché funziona la seconda istruzione if? Sento che mi manca qualcosa di molto fondamentale qui.
Qualsiasi intuizione è apprezzata.
Edit2 (Ri-proposizione domanda un po '):
posso accettare il problema di precisione matematica, ma la mia domanda ora è: perché il passaggio del mouse sopra valutare correttamente? Questo vale anche per la finestra intermedia. Incollo il codice dalla prima istruzione if nella finestra intermedia e viene valutato false.
Aggiornamento
Prima di tutto, grazie mille per tutte le grandi risposte.
Ho anche problemi a ricreare questo in un altro progetto sulla stessa macchina. Guardando le impostazioni del progetto, non vedo differenze. Guardando l'IL tra i progetti, non vedo differenze. Guardando allo smontaggio, non vedo differenze apparenti (oltre agli indirizzi di memoria). Eppure, quando metto a punto il progetto originale, vedo: screenshot of problem http://i30.tinypic.com/ega874.png
finestra immediata mi dice che il caso è falso, ma il codice cade nella condizionale.
In ogni caso, la risposta migliore, penso, è quella di prepararsi all'aritmetica in virgola mobile in queste situazioni. Il motivo per cui non ho potuto lasciarlo andare ha più a che fare con i calcoli del debugger che differiscono dal runtime. Quindi grazie infinite a Brian Gideon e stephentyrone per alcuni commenti molto perspicaci.
"1e3" è una costante mobile o una doppia costante? –
Se riesci ad accettare il problema della precisione matematica, perché stai ancora chiedendo? Il problema è che 1e-3 non può essere rappresentato con precisione, e quindi 1e3 * 1e-3 non è 1.0, è qualcosa di simile, ma non del tutto, il che significa che fallisce. –
"1e3" viene compilato come un doppio perché vedo l'istruzione ldc.r8 nel mio output IL. –