2009-07-20 6 views
5

सी ++ को पोर्ट जावा कोड करने का प्रयास कर मैंने कुछ अजीब व्यवहार पर ठोकर खाई है। मुझे काम में दोगुना जोड़ा नहीं जा सकता है (भले ही कंपाइलर विकल्प/एफपी: सख्त जिसका अर्थ है "सही" फ्लोटिंग पॉइंट गणित विजुअल स्टूडियो 2008 में सेट है)।एक विशिष्ट विजुअल स्टूडियो 2008 प्रोजेक्ट में युगल गलत तरीके से क्यों जोड़े गए हैं?

double a = 0.4; 
/* a: 0.40000000000000002, correct */ 

double b = 0.0 + 0.4; 
/* b: 0.40000000596046448, incorrect 
(0 + 0.4 is the same). It's not even close to correct. */ 

double c = 0; 
float f = 0.4f; 
c += f; 
/* c: 0.40000000596046448 too */ 

एक अलग परीक्षण परियोजना में मैंने स्थापित किया है यह ठीक काम करता है (/ fp: आईईईई 754 के अनुसार सख्त व्यवहार करता है)।

कोई ऑप्टिमाइज़ेशन और एफपी: सख्त के साथ विजुअल स्टूडियो 2008 (मानक) का उपयोग करना।

कोई विचार? क्या यह वास्तव में तैरने के लिए छंटनी कर रहा है? इस परियोजना को वास्तव में जावा और सी ++ दोनों पक्षों पर समान व्यवहार की आवश्यकता है। मुझे वीसी ++ में डीबग विंडो से पढ़कर सभी मूल्य मिल गए।

समाधान: _fpreset(); // बैरी केली के विचार ने इसे हल किया। एक पुस्तकालय एफपी परिशुद्धता को कम करने के लिए सेटिंग कर रहा था।

+2

क्या आप संकलित करने के लिए उपयोग की जाने वाली सटीक कमांड लाइन के साथ एक छोटा पूर्ण परीक्षण प्रोग्राम पोस्ट कर सकते हैं (आउटपुट विंडो आदि देखें), जो समस्या का प्रदर्शन करता है? एकमात्र तरीका जिसे मैं पुन: उत्पन्न कर सकता हूं वह इसके बजाय 0.0f + 0.4f का उपयोग कर रहा है। –

+0

क्या हम मान सकते हैं कि आप फ़्लोटिंग पॉइंट प्रकारों के अपर्याप्तता से अवगत हैं? 7 दशमलव स्थानों पर सटीक होने के कारण आमतौर पर ठीक प्रिंटिंग परिशुद्धता 6. –

+0

@Evan है, उसका उदाहरण फ़्लोटिंग पॉइंट अपर्याप्तता द्वारा समझाया जाएगा उससे अधिक है। – Kevin

उत्तर

8

एकमात्र चीज जिसे मैं सोच सकता हूं शायद आप लाइब्रेरी या डीएलएल के खिलाफ जुड़ रहे हैं जिसने नियंत्रण शब्द के माध्यम से सीपीयू परिशुद्धता को संशोधित किया है।

क्या आपने समस्याग्रस्त गणना से पहले float.h से _fpreset() पर कॉल करने का प्रयास किया है?

+0

यह उन पंक्तियों के साथ कुछ होना चाहिए, लेकिन 0.0 + 0.4 भी गणना है? संकलन समय पर इसका मूल्यांकन नहीं किया जा सकता है? डिस्सेप्लोरिंग की जांच करना यह निर्धारित कर सकता है कि रनटाइम फ्लोट मोड के साथ कुछ भी करने के लिए, या संकलन समय में कुछ गलत हो गया है या नहीं। –

+0

यकीन है कि यह हो सकता है, लेकिन अगर यह इतना आसान था, तो पुन: पेश करना आसान होगा, नहीं? –

+0

मुझे पता नहीं है, शायद परियोजना में कुछ और निर्दिष्ट है/fp: बेवकूफ या समकक्ष। मेरा निजी पसंदीदा एक स्रोत फ़ाइल होगा, जो कि नई लाइन-समाप्त नहीं है और इसलिए कार्यक्रम ने अपरिभाषित व्यवहार किया है, हालांकि मुझे कभी भी देखने की ज्यादा उम्मीद नहीं है कि जंगली में एक बग का कारण बनता है ... –

3

हां, यह निश्चित रूप से तैरने के लिए छेड़छाड़ कर रहा है। जैसा कि आप "गलत" मामले में करते हैं, मुझे वही वैल्यू प्रिंटिंग float f = 0.4 मिलता है। आज़माएं:

double b = 0.0 + (double) 0.4; 

सवाल यह है कि यह तैरने के लिए क्यों छेड़छाड़ कर रहा है। 0.0 + 0.4 को एकल-परिशुद्धता अभिव्यक्ति के रूप में इलाज के लिए मानक में कोई बहाना नहीं है, क्योंकि फ्लोटिंग पॉइंट अक्षर दो-परिशुद्धता हैं जब तक कि उनके पास अन्यथा कहने के लिए कोई प्रत्यय न हो।

तो कुछ आपकी सेटिंग्स में हस्तक्षेप करना चाहिए, लेकिन मुझे नहीं पता कि क्या।

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