2012-03-23 87 views
5

समानता के लिए युगल की तुलना करते समय, हमें सहनशीलता स्तर देना होगा, क्योंकि फ़्लोटिंग-पॉइंट गणना त्रुटियों को पेश कर सकती है। उदाहरण के लिए:निरंतर असाइनमेंट की फ़्लोटिंग-पॉइंट तुलना

double x; 
double y; 
x = f(); 
y = g(); 

if (fabs(x-y)<epsilon) { 
    // they are equal! 
} else { 
    // they are not! 
} 

हालांकि, अगर मैं बस एक निरंतर मूल्य, आवंटित किसी भी गणना के बिना, मैं अभी भी एप्सिलॉन की जाँच करने की आवश्यकता है?

double x = 1; 
double y = 1; 

if (x==y) { 
    // they are equal! 
} else { 
    // no they are not! 
} 

== तुलना पर्याप्त है? या मुझे fabs(x-y)<epsilon फिर से करने की ज़रूरत है? क्या असाइन करने में त्रुटि लागू करना संभव है? क्या मैं भी पागल हूँ?

कास्टिंग के बारे में कैसे (double x = static_cast<double>(100))? क्या वह फ्लोटिंग-पॉइंट त्रुटि भी पेश करेगा?

मैं लिनक्स पर सी ++ का उपयोग कर रहा हूं, लेकिन यदि यह भाषा से अलग है, तो मैं भी इसे समझना चाहता हूं।

+0

चाहे आपको एक ईपीएसलॉन की आवश्यकता हो, स्थिति पर निर्भर करता है। जैसे जब आपको एक संक्रमणीय समानता की आवश्यकता होती है ('a == b && b == c' का अर्थ है 'a == c'), तो आप एक ईपीएसलॉन का उपयोग नहीं कर सकते हैं। बीटीडब्लू, 'डबल एक्स = 1' का अर्थ पहले से ही है' डबल एक्स = स्टेटिक_कास्ट (1) ' – MSalters

उत्तर

3

वास्तव में, यह मूल्य और कार्यान्वयन पर निर्भर करता है। सी ++ मानक (मसौदा n3126) इस 2.14.4 Floating literals में कहना है:

तो बढ़ाया मूल्य अपने प्रकार के लिए प्रदर्शनीय मानों की श्रेणी में है, परिणाम बढ़ाया मूल्य है अगर प्रदर्शनीय, बाकी को बड़ा या छोटा प्रदर्शनीय कार्यान्वयन-परिभाषित तरीके से चुने गए स्केल किए गए मान के नजदीक मूल्य। , आप मूल्य प्राप्त

दूसरे शब्दों में, यदि मान को उसी प्रदर्शनीय है (के रूप में अपने स्थिर कलाकारों में 100 और 1 IEEE754 में है,)। अन्यथा (जैसे कि 0.1) आपको कार्यान्वयन-परिभाषित निकट मिलान (ए) मिलता है। अब मैं एक कार्यान्वयन के बारे में बहुत चिंतित हूं जिसने एक ही इनपुट टोकन के आधार पर अलग करीबी मैच चुना है, लेकिन संभव है।


(क) वास्तव में, कि पैरा दो तरह से पढ़ा जा सकता है, या तो कार्यान्वयन चयन करने के लिए या तो निकटतम अधिक या निकटतम कम मूल्य की परवाह किए बिना मुक्त जिनमें से वास्तव में सबसे करीब है है, या यह चयन करना होगा वांछित मूल्य के सबसे नज़दीकी।

यदि उत्तरार्द्ध, यह इस जवाब को नहीं बदलता है, हालांकि आपको केवल दो प्रतिनिधित्व करने योग्य प्रकारों के मध्य बिंदु पर एक फ्लोटिंग पॉइंट मान हार्डकोड करना है और कार्यान्वयन एक बार फिर से चुनने के लिए स्वतंत्र है।

उदाहरण के लिए, संचयी त्रुटियों को कम करने के लिए बैंकर के गोलाकार लागू होने के कारण यह अगले उच्च और अगले निचले हिस्से के बीच वैकल्पिक हो सकता है - संचयी त्रुटियों को कम करने के लिए।

+0

कुछ कार्यान्वयन 'फ्लोट' के नजदीक 'डबल' मान ढूंढकर 'फ्लोट' अक्षर का मूल्यांकन करने लगते हैं, और उसके बाद इसे गोल करते हैं 'float'। यह कभी-कभी 'फ्लोट' अक्षर का कारण बन सकता है जिसका वास्तविक मूल्य 'डबल' से थोड़ा ऊपर या नीचे होता है जो वास्तव में दो निकटतम 'फ्लोट' मानों के बीच होता है, जो एक मूल्य असाइन किया जाता है जो निकटतम नहीं होता है। – supercat

0

नहीं यदि आप शाब्दिक आवंटित वे एक ही :)

इसके अलावा अगर आप एक ही मूल्य के साथ शुरू और एक ही आपरेशन करते हैं, वे एक ही होना चाहिए होना चाहिए।

चल बिन्दु मान गैर सटीक हैं, लेकिन आपरेशन लगातार परिणाम चाहिए :)

0

दोनों मामले आखिरकार कार्यान्वयन परिभाषित प्रतिनिधित्व के अधीन हैं।

फ़्लोटिंग पॉइंट मानों और उनके प्रतिनिधित्वों का संग्रहण हो सकता है - पता या निरंतर लोड? तेजी से गणित द्वारा अनुकूलित? रजिस्टर चौड़ाई क्या है? क्या यह एक एसएसई रजिस्टर में संग्रहीत है? कई भिन्नताएं मौजूद हैं।

यदि आपको सटीक व्यवहार और पोर्टेबिलिटी की आवश्यकता है, तो इस कार्यान्वयन परिभाषित व्यवहार पर भरोसा न करें।

0

आईईईई -754, जो फ्लोटिंग पॉइंट नंबरों का मानक सामान्य कार्यान्वयन है, के लिए फ़्लोटिंग-पॉइंट ऑपरेशंस की आवश्यकता होती है जिसके परिणामस्वरूप असीमित-सटीक परिणाम के निकटतम प्रतिनिधित्व योग्य मूल्य होता है। इस प्रकार आप जिस भी ऑपरेशन का सामना करेंगे, उसके बाद आप जो भी ऑपरेशन करेंगे, उसके साथ-साथ चेन में पहले किए गए संचालन से गोल करने वाली त्रुटियों के प्रसार के साथ-साथ आप का सामना करना पड़ेगा। फ्लोट प्रति से अधिक नहीं हैं। और वैसे, epsilon गणना और गणना की जानी चाहिए, आप उस पर किसी भी संख्यात्मक पुस्तक से परामर्श कर सकते हैं।

फ़्लोटिंग पॉइंट नंबर उनके मंटिसा की लंबाई तक पूर्णांक का प्रतिनिधित्व कर सकते हैं। तो उदाहरण के लिए यदि आप एक int से एक डबल तक कास्ट करते हैं, तो यह हमेशा सटीक होगा, लेकिन एक फ्लोट में डालने के लिए, यह अब बहुत बड़े पूर्णांक के लिए सटीक नहीं होगा।

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

अब, कई कंप्यूटर्स के पास एक वैकल्पिक स्विच है जो आईईईई -754 संगतता को अक्षम करता है। फिर समझौता किया जाता है। Denormalized संख्या (बहुत छोटी संख्या जहां एक्सपोनेंट सबसे कम संभव मूल्य तक पहुंच गया है) अक्सर शून्य के रूप में माना जाता है, और बिजली, logarithm, वर्ग, और 1/(x^2) के कार्यान्वयन में अनुमान लगाया जा सकता है, लेकिन जोड़/घटाव, तुलना और गुणा को उनके गुणों को संख्याओं के लिए बनाए रखना चाहिए जिन्हें वास्तव में प्रदर्शित किया जा सकता है।

0

आसान उत्तर: स्थिरांक के लिए == ठीक है। दो अपवाद है जो आप के बारे में पता होना चाहिए रहे हैं:

प्रथम अपवाद:

0.0 == -0,0

वहाँ एक नकारात्मक शून्य जो आईईईई 754 मानक के लिए बराबर की तुलना करता है। इसका मतलब यह है 1/अनंत == 1/-INFINITY जो f (x) == च (y) => x == y

दूसरा अपवाद टूट जाता है:

NaN = NaN

यह नोटा नम्बर की एक विशेष चेतावनी है जो यह पता लगाने की अनुमति देती है कि कोई संख्या उन अनुप्रयोगों पर NaN है, जिनके पास कोई परीक्षण फ़ंक्शन उपलब्ध नहीं है (हां, ऐसा होता है)।