2012-02-10 2 views
9

Questo è davvero un bug strano per me e mi ci è voluto molto tempo per capire cosa sta succedendo. Per semplificare le cose e riprodursi, basta creare un'applicazione console Win32 vuoto utilizzando VS2005 e utilizzando questo codice nel metodo principale:Perché il calcolo e la trasmissione fluttuanti mostrano risultati diversi nella configurazione di debug e release?

float a = 411.00418f; 
float b = 1.0f; 
float c = 0.076279849f; 
unsigned short result = (unsigned short)((a-b)/c); 
unsigned short result2 = (unsigned short)((float)((a-b)/c)); 
// Debug: 5374, 5375 
// Release: 5374, 5374 
printf("%d, %d\n", result, result2); 

Perché result2 mostra valore diverso in modalità debug/release?

risposta

10

In MSVC, la modalità di virgola mobile predefinita è precise (/fp:precise). Ciò significa che l'ottimizzatore può eseguire determinate ottimizzazioni per migliorare l'accuratezza o le prestazioni.

Provare a cambiare modalità su strict (/fp:strict). Questo farà sì che il compilatore segua le rigide regole a virgola mobile sull'arrotondamento e così via.

(EDIT: strict (/fp:strict) non sembra funzionare in questo caso ...)

Se si guarda lo smontaggio della compilazione ottimizzata, si può vedere che l'intero calcolo è stato piegato e ottimizzata fuori.

push 5374     ; 000014feH 
push 5374     ; 000014feH 
push OFFSET [email protected][email protected][email protected] 
call DWORD PTR __imp__printf 
add esp, 12     ; 0000000cH 

EDIT: Questo appare come un bug del compilatore ottimizzatore per me.

Sotto strict (/fp:strict), il codice seguente produce diversi risultati:

float a = 411.00418f; 
float b = 1.0f; 
float c = 0.076279849f; 

unsigned short result1 = (unsigned short)((float)((a-b)/c)); 

float d = (float)((a-b)/c); 
unsigned short result2 = (unsigned short)(d); 

uscita:

5374, 5375 

estraendo la (float)((a-b)/c) in un'assegnazione separata non dovrebbe influenzare i risultati sotto strict (/fp:strict).


Conosco uno dei ragazzi che lavorano sulla ottimizzatore MSVC. Invierò un bug report a lui.

Aggiornamento:

Ecco la loro risposta:

Ciao Alex, grazie per questo bug report. Proverò a risolvere questo problema per la release VC++ imminente di , ma potrebbe non riuscire.

FWIW, il bug non riproduce se si lancia/arch: SSE2, e dato che permettiamo/arch: SSE2 per impostazione predefinita per la prossima VC++ rilasciare (https://connect.microsoft.com/VisualStudio/retroazione/dettagli/688.736/compilatore genera-SSE-istruzioni-senza-arch-SSE).

Quindi, il comportamento predefinito mostrerà che questo errore è stato risolto. Ma se si ritorna al vecchio modello FP (throw/arch: IA32) il bug potrebbe essere ancora presente.

Eric

Così hanno confermato questo come un bug.

+0

Ho impostato il "modello a virgola mobile" su "Strict (/ fp: strict)" e il risultato è lo stesso. Mi sono perso qualcosa qui? –

+0

L'ho notato anche io. Sto provando a capirlo anche io. Nella build ottimizzata, l'ottimizzatore sta piegando tutto il calcolo. Io * penso * che è dove non sta rispettando il comportamento di arrotondamento rigoroso. – Mysticial

+0

In realtà il mio progetto utilizza C++/CLI in vs2010, quindi forse anche questo è influenzato? –

Problemi correlati