दिलचस्प पोस्ट
जावा में एक कस्टम जेबटन बनाना क्या संख्याओं को मान्य करने के लिए जावास्क्रिप्ट में isNumeric जैसे कोई फ़ंक्शन है? PHP स्ट्रिंग से विशेष वर्ण निकालें जब कोई सॉर्ट ऑर्डर निर्दिष्ट नहीं होता है तो मॉगोडाब सॉर्ट रिकॉर्ड कैसे करता है? डायलॉग्रेग्मेंट का उपयोग करके तिथि पिक्चर से तिथि प्राप्त करें Google मानचित्र एपीआई वी 3 में एपीआई कुंजी क्या है? एक श्रोता पूर्वपरिसिस्ट में सुरक्षा कंटैक्स्ट को इंजेक्शन या उपनिर्धारित 2 में Symfony2 में यूजर को बनाने के लिए या अपडेट किया गया कारण कारण परिपत्र संदर्भ त्रुटि सी +11 रिवर्स रेंज-आधारित फॉर-लूप आंतरिक बनाम बनाम कहाँ दोस्ताना नाम से सीरियल पोर्ट कैसे खोलें? शुद्ध सीएसएस पतन / div विस्तृत करें मैक पर कस्टम बटन काम नहीं करते (बटनयूआई) टैबकॉन्ट्रॉल से टैबपेज को कैसे छिपाएंगे लगातार Amortized समय मैं किसी अन्य रेपो के साथ एक git submodule की जगह कैसे करूं?

क्या समानता के लिए फ्लोटिंग पॉइंट वैल्यू 0 से जांचना सुरक्षित है?

मुझे पता है कि आप समानता पर डबल या दशमलव प्रकार के मूल्यों के बीच समानता पर भरोसा नहीं कर सकते, लेकिन मैं सोच रहा हूं कि 0 एक विशेष मामला है।

जबकि मैं 0.00000000000001 और 0.00000000000002 के बीच imprecisions समझ सकता है, 0 बस गड़बड़ करने के लिए बहुत मुश्किल लगता है क्योंकि यह सिर्फ कुछ नहीं है यदि आप कुछ भी नहीं कर रहे हैं, तो यह अब और कुछ नहीं है।

लेकिन मुझे इस विषय के बारे में ज्यादा जानकारी नहीं है, इसलिए यह कहना मेरे लिए नहीं है।

double x = 0.0; return (x == 0.0) ? true : false; 

क्या यह हमेशा सच हो जाएगा?

वेब के समाधान से एकत्रित समाधान "क्या समानता के लिए फ्लोटिंग पॉइंट वैल्यू 0 से जांचना सुरक्षित है?"

यह अपेक्षा करने के लिए सुरक्षित है कि तुलना true हो जाएगी और यदि केवल दोहरी चर में 0.0 का मान होता है (जो आपके मूल कोड स्निपेट में है, निश्चित रूप से, मामला)। यह == ऑपरेटर के शब्दों के साथ संगत है। a == b अर्थ है " a बराबर है b "

यह सुरक्षित नहीं है (क्योंकि यह सही नहीं है ) उम्मीद है कि कुछ गणना का परिणाम शून्य (या अधिक सामान्यतः, फ्लोटिंग प्वाइंट) अंकगणित में शून्य हो जाएगा, जब भी शुद्ध गणित में समान गणना का परिणाम शून्य होता है। इसका कारण यह है कि जब गणना जमीन में आती है, तो फ्लोटिंग प्वाइंट सटीक त्रुटि दिखाई देती है – एक अवधारणा जो गणित में वास्तविक संख्या अंकगणित में मौजूद नहीं है।

यदि आपको "समानता" तुलना की बहुत कुछ करने की आवश्यकता है, तो यह तुलना करने के लिए .NET 3.5 में थोड़ा सहायक फ़ंक्शन या एक्सटेंशन विधि लिखने का एक अच्छा विचार हो सकता है:

 public static bool AlmostEquals(this double double1, double double2, double precision) { return (Math.Abs(double1 - double2) <= precision); } 

इसका उपयोग निम्नलिखित तरीके से किया जा सकता है:

 double d1 = 10.0 * .1; bool equals = d1.AlmostEquals(0.0, 0.0000001); 

आपके सरल नमूने के लिए, यह परीक्षा ठीक है। लेकिन इसके बारे में क्या है:

 bool b = ( 10.0 * .1 - 1.0 == 0.0 ); 

याद रखें कि .1 द्विआधारी में एक दशमलव दोहरा रहा है और इसे बिल्कुल नहीं दर्शाया जा सकता है। फिर इस कोड की तुलना करें:

 double d1 = 10.0 * .1; // make sure the compiler hasn't optimized the .1 issue away bool b = ( d1 - 1.0 == 0.0 ); 

वास्तविक परिणामों को देखने के लिए मैं आपको एक परीक्षा चलाने के लिए छोड़ दूँगा: आप इसे उसी तरह याद रख सकते हैं

Double.Equals के लिए एमएसडीएन प्रविष्टि से:

तुलना में सटीक

बराबर विधि सावधानी के साथ इस्तेमाल किया जाना चाहिए, क्योंकि दो मानों की भिन्न परिशुद्धता के कारण दो स्पष्ट रूप से समान मूल्य असमान हो सकते हैं। निम्न उदाहरण बताता है कि डबल मान .3333 और डबल 1 द्वारा 3 से विभाजित करके लौटा असमान है।

समानता की तुलना करने के बजाय, एक अनुशंसित तकनीक में दो मानों (जैसे मानों में से एक .01%) के बीच अंतर के स्वीकार्य मार्जिन को परिभाषित करना शामिल है। यदि दो मानों के बीच के अंतर का पूर्ण मूल्य उस मार्जिन से कम या उसके बराबर है, तो अंतर सटीकता में अंतर के कारण होने की संभावना है और इसलिए, मूल्य बराबर होने की संभावना है। निम्न उदाहरण इस तकनीक का उपयोग करके तुलना करने के लिए .33333 और 1/3, दो डबल मान जो पिछले कोड उदाहरण को असमान पाया गया।

इसके अलावा, डबल देखें। एप्सिलॉन

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

 float f = 0.1F; bool b1 = (f == 0.1); //returns false bool b2 = (f == 0.1F); //returns true 

समस्या यह है कि प्रोग्रामर कभी-कभी भूल जाते हैं कि तुलना के लिए निहित प्रकार कास्ट (डबल से फ्लोट) की तुलना के लिए हो रहा है और इससे बग में परिणाम होता है

यदि संख्या सीधे फ्लोट या डबल को सौंपी गई थी तो शून्य या कोई भी पूरी संख्या के खिलाफ परीक्षण करने के लिए सुरक्षित है जो कि एक फ्लोट के लिए दो या 24 बिट के लिए 53 बिट में प्रदर्शित किया जा सकता है।

या इसे किसी अन्य तरीके से रखने के लिए आप हमेशा दोहराए और पूर्णांक मान को आवंटित कर सकते हैं और फिर दोहरे परत की एक ही पूर्णांक की तुलना कर लें और इसकी गारंटी दें कि यह समान होगा।

आप पूरी संख्या को निर्दिष्ट करके भी शुरू कर सकते हैं और समान संख्याओं को जोड़कर, घटाना या संपूर्ण संख्याओं से गुणा करके चिपकाकर काम करना जारी रख सकते हैं (परिणाम संभालने के लिए 24 बिट से कम एक फ्लोट ABD 53 बिट्स के लिए डबल के लिए)। तो आप कुछ नियंत्रित परिस्थितियों में पूर्णांक के रूप में फ़्लोट्स और डबल्स का इलाज कर सकते हैं।

नहीं, यह ठीक नहीं है। तथाकथित denormalized मूल्य (असामान्य), जब 0.0 के बराबर की तुलना, झूठी (गैर शून्य) के रूप में तुलना की जाएगी, लेकिन जब एक समीकरण में इस्तेमाल किया जाएगा सामान्यीकृत (0.0 हो जाएगा)। इस प्रकार, इसे विभाजन के जरिए शून्य से बचने के लिए एक तंत्र के रूप में प्रयोग करना सुरक्षित नहीं है। इसके बजाय, 1.0 जोड़ें और 1.0 की तुलना करें। इससे यह सुनिश्चित होगा कि सभी उप-नियमों को शून्य मान लिया जाए।

दरअसल, मुझे लगता है कि 0.0 के मुकाबले एक डबल मान की तुलना करने के लिए निम्नलिखित कोड का उपयोग करना बेहतर है:

 double x = 0.0; return (Math.Abs(x) < double.Epsilon) ? true : false; 

फ्लोट के लिए भी:

 float x = 0.0f; return (Math.Abs(x) < float.Epsilon) ? true : false;