floating point क्या "एप्सिलॉन" वास्तव में अस्थायी-बिंदु कम्प्यूटेशंस में कुछ भी गारंटी देता है?




floating-point floating-accuracy (2)

"फ्लोट से काम करते समय आपको एक एपिसलॉन का उपयोग करना चाहिए" सामान्यतः (न केवल शून्य) तुलना में, फ्लोटिंग-पॉइंट कम्प्यूटेशंस की सतही समझ के साथ प्रोग्रामर्स की घुटने-झटका प्रतिक्रिया है।

यह आमतौर पर असहनीय है क्योंकि यह आपको गोल त्रुटियों के प्रसार को कम करने के बारे में नहीं बताता है, यह आपको बताता नहीं है कि कैसे रद्दीकरण या अवशोषण समस्याओं से बचने के लिए और यहां तक ​​कि जब आपकी समस्या वास्तव में दो फ्लोटों की तुलना से संबंधित है आपको बता नहीं है कि आप क्या कर रहे हैं उसके लिए एप्सिलॉन का मूल्य सही है

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

गोल त्रुटियों के प्रचार के संबंध में, विशेष विश्लेषक मौजूद हैं जो आपको इसका अनुमान लगाने में मदद कर सकते हैं, क्योंकि यह हाथ से करने के लिए एक कठिन काम है।

समस्या को कम करने के लिए चलिए अब कहते हैं कि मैं float एस पर अभिव्यक्ति a / (b - c) गणना करना चाहता हूं।

यह सुनिश्चित करने के लिए कि परिणाम सार्थक है, मैं जांच सकता हूँ कि b और c समान हैं:

float EPS = std::numeric_limits<float>::epsilon();
if ((b - c) > EPS || (c - b) > EPS)
{
    return a / (b - c);
}

लेकिन मेरे परीक्षण से पता चलता है कि यह या तो सार्थक परिणाम की गारंटी के लिए पर्याप्त नहीं है और न ही परिणाम प्रदान करने में असफल रहने के कारण यह संभव है।

मामला एक:

a = 1.0f;
b = 0.00000003f;
c = 0.00000002f;

परिणाम: यदि कंडीशन नहीं मिला है, लेकिन अभिव्यक्ति एक सही परिणाम 100000008 ('फ्लोट्स सटीक के लिए) का उत्पादन करेगी।

केस 2:

a = 1e33f;
b = 0.000003;
c = 0.000002;

परिणाम: अगर हालत पूरी हो गई है, लेकिन अभिव्यक्ति एक सार्थक परिणाम नहीं उत्पन्न करती है +1.#INF00

मुझे परिणाम की जांच करने के लिए इसे और अधिक विश्वसनीय पाया, तर्क नहीं:

const float INF = numeric_limits<float>::infinity();
float x = a / (b - c);
if (-INF < x && x < INF)
{
     return x;
}

लेकिन फिर क्या एप्सिलॉन है और हर कोई कह रहा है कि एप्सिलॉन का इस्तेमाल करना अच्छा है?


एपसीलॉन का उपयोग यह निर्धारित करने के लिए किया जाता है कि क्या दो अंकों को गोलाकार त्रुटि के अधीन है, "बराबर" माना जाने वाला पर्याप्त करीब है ध्यान दें कि fabs(b/c - 1) < EPS तुलना में fabs(bc) < EPS , और इससे भी बेहतर - आईईईई फ्लोट के डिज़ाइन के लिए धन्यवाद - abs(*(int*)&b - *(int*)&c) < EPSI (जहां ईपीएसआई कुछ छोटे पूर्णांक है)।

आपकी समस्या एक अलग प्रकृति का है, और संभवत: आदानों के बजाय परिणाम का परीक्षण करने की वारंट।





epsilon