2012-02-10 14 views
9

यह वास्तव में मेरे लिए एक अजीब बग है और मुझे यह पता लगाने में काफी समय लगा कि क्या हो रहा है। चीजों को आसान बनाने और पुन: पेश करने के लिए, बस VS2005 का उपयोग कर एक खाली Win32 सांत्वना आवेदन बना सकते हैं और मुख्य विधि में इस कोड का उपयोग करें:फ्लोटिंग गणना और कास्टिंग क्यों डीबग और रिलीज कॉन्फ़िगरेशन में अलग-अलग परिणाम दिखाता है?

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 डिबग/रिलीज मोड में अलग अलग मूल्य पता चलता है?

उत्तर

10

एमएसवीसी में, डिफ़ॉल्ट फ़्लोटिंग-पॉइंट मोड precise (/fp:precise) है। इसका अर्थ यह है कि अनुकूलक सटीकता या प्रदर्शन को बेहतर बनाने के लिए कुछ अनुकूलन कर सकता है।

strict (/fp:strict) पर मोड बदलने का प्रयास करें। यह संकलक को गोलाकार और इस तरह के सख्त फ़्लोटिंग-पॉइंट नियमों का पालन करेगा।

(संपादित करें: strict (/fp:strict) इस मामले में काम करने के लिए ... प्रतीत नहीं होता)

आप अनुकूलित निर्माण के disassembly को देखें, तो आप देख सकते हैं कि पूरे गणना जोड़ दिया गया है और बाहर अनुकूलित।

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

संपादित करें: यह मेरे लिए एक संकलक अनुकूलक बग की तरह दिखता है।

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

आउटपुट::

5374, 5375 

एक अलग काम में (float)((a-b)/c) खींच strict (/fp:strict) तहत परिणामों को प्रभावित नहीं करना चाहिए

strict (/fp:strict) के तहत, निम्नलिखित कोड अलग परिणाम पैदा करता है।


मैं लोग MSVC अनुकूलक पर काम में से एक को पता है। मैं उसे एक बग रिपोर्ट भेजूंगा।

अद्यतन:

हाय एलेक्स, इस बग रिपोर्ट के लिए धन्यवाद:

यहाँ उनकी प्रतिक्रिया है। मैं आगामी वीसी ++ रिलीज के लिए इसे ठीक करने का प्रयास करूंगा, लेकिन यह इसे नहीं बना सकता है।

Fwiw, अगर तुम फेंक/मेहराब बग पुन: पेश नहीं करता है: SSE2, और तब से हम सक्षम कर रहे हैं/मेहराब: अगले कुलपति के लिए डिफ़ॉल्ट रूप से SSE2 ++ जारी (https://connect.microsoft.com/VisualStudio/प्रतिक्रिया/विवरण/688,736/संकलक उत्पन्न करता है-SSE-निर्देश-बिना-कट्टर SSE)।

तो, डिफ़ॉल्ट व्यवहार दिखाएगा कि यह बग ठीक है। लेकिन अगर आप पुराने एफपी मॉडल (फेंक/आर्क: आईए 32) पर वापस लौटते हैं तो बग अभी भी मौजूद हो सकता है।

एरिक

तो वे एक बग के रूप में इस की पुष्टि की है।

+0

मैंने "फ़्लोटिंग पॉइंट मॉडल" को "सख्त (/ fp: सख्त)" पर सेट किया है और नतीजा वही है। क्या मुझसे यहां पर कुछ छूट गया? –

+0

मैंने यह भी देखा। मैं इसे भी समझने की कोशिश कर रहा हूं। अनुकूलित निर्माण में, अनुकूलक सभी गणना को तब्दील कर रहा है। मैं * सोचता हूं * वह वहीं है जहां यह सख्त दौर व्यवहार का सम्मान नहीं कर रहा है। – Mysticial

+0

वास्तव में मेरी परियोजना बनाम 2010 में सी ++/सीएलआई का उपयोग कर रही है, तो हो सकता है कि यह भी प्रभावित हो? –

संबंधित मुद्दे