2012-02-10 22 views
9

Bu gerçekten benim için garip bir hata olduğunu ve neler olduğunu anlamaya bana uzun zaman aldı. şeyleri basitleştirmek ve yeniden oluşturmak için, sadece VS2005 kullanarak bir boş Win32 konsol uygulaması oluşturmak ve ana yönteminde bu kodu kullanın:Yüzer hesaplamalar ve dökümler, neden hata ayıklama ve bırakma yapılandırmasında farklı sonuçlar gösterir?

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); 
result2 ayıklama/sürüm modunda farklı bir değer gösterir Neden

? MSVC yılında

cevap

10

, varsayılan kayan nokta modu precise (/fp:precise) olduğunu. Optimizer, doğruluğu veya performansı artırmak için belirli optimizasyonlar yapabilir. strict (/fp:strict) için modunu değiştirerek

deneyin. Bu, derleyicinin yuvarlamadaki katı kayan nokta kurallarını takip etmesini sağlar.

(Düzeltme: strict (/fp:strict) ... Bu durumda çalışmak için görünmüyor)

Optimize edilmiş yapı sökme bakarsak, tüm hesaplama katlanmış ve dışarı optimize edildiğini görebiliriz.

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

DÜZENLEME: Bu benim için derleyici iyileştirici böcek gibi görünüyor. strict (/fp:strict) altında sonuçları etkilememelidir ayrı atama içine (float)((a-b)/c) çekilmesi

5374, 5375 

:

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); 

Çıkış: strict (/fp:strict) altında

, şu kod farklı sonuçlar üretir.


ben MSVC optimizer üzerinde çalışmak adamlardan biri biliyorum. Ona bir hata raporu göndereceğim.

Güncelleme:

Merhaba Alex, bu hata raporu için teşekkürler:

İşte onların tepki. Bunu, yaklaşan VC++ sürümü için düzeltmeye çalışacağım, ancak bunu yapmayabilir. https://connect.microsoft.com/VisualStudio (sonraki VC için varsayılan olarak SSE2 serbest ++:

FWIW, böcek sen/kemer atmak durumunda yeniden değildir: SSE2 ve biz /kemer etkinleştiriyorsanız beri/geri besleme/bilgilerini/688.736/derleyici üretir-eğ-kitabı-olmayan-kemer SSE).

Yani, varsayılan davranış bu hata düzeltildi olduğunu gösterecektir. Hata hala mevcut olabilir: Ama eğer tekrar eski FP modeli (IA32 atış/kemer) dönerler. Eric

Böylece bir hata olarak bu teyit ettik.

+0

"Kayan nokta modeli" ni "Strict (/ fp: strict)" olarak ayarlıyorum ve sonuç aynı. Burada bir şey mi özledim? –

+0

Ben de bunu fark ettim. Ben de anlamaya çalışıyorum. Optimize edilmiş yapıda, optimize edici tüm hesaplamaları katlıyor. Ben * düşünün * katı yuvarlama davranışına saygı duymadığı yer burası. – Mysticial

+0

Aslında benim projem vs2010'da C++/CLI kullanıyor, bu belki de bu durumdan etkileniyor mu? –

İlgili konular