समानता के लिए फ्लोटिंग पॉइंट वैल्यू की तुलना करते समय, दो अलग-अलग दृष्टिकोण होते हैं:
NaN
खुद के बराबर नहीं है, जो IEEE 754 विनिर्देश से मेल खाता है ।NaN
खुद के बराबर होने के नाते, जो रिफ्लेक्सिटी की गणितीय संपत्ति प्रदान करता है जो एक समानता संबंध की परिभाषा के लिए आवश्यक है
सी # (में बिंदु प्रकार चल आईईईई में बनाया गया float
और double
) के लिए आईईईई अर्थ विज्ञान का पालन करें ==
और !=
(और संबंधपरक ऑपरेटर की तरह <
), लेकिन के लिए रिफ्लेक्सिविटी सुनिश्चित object.Equals
, IEquatable<T>.Equals
(और CompareTo
)।
अब एक पुस्तकालय पर विचार करें जो float
/ के ऊपर वेक्टर संरचना प्रदान करता है double
। इस तरह का एक वेक्टर प्रकार अधिभार ==
/ !=
और ओवरराइड object.Equals
/ होगा IEquatable<T>.Equals
।
क्या हर कोई पर सहमत होती है ==
/ !=
आईईईई अर्थ विज्ञान का पालन करना चाहिए। सवाल यह है कि क्या इस तरह की लाइब्रेरी Equals
पद्धति को लागू करना चाहिए (जो समानता ऑपरेटरों से अलग हो) एक तरह से रिफ्लेक्टिव है या एक तरह से IEEE शब्दार्थ से मेल खाती है।
आईईईई शब्दार्थ का उपयोग करने के लिए तर्क Equals
:
- यह IEEE 754 को फॉलो करता है
यह (संभवतः अधिक) तेज़ी से है क्योंकि यह SIMD निर्देशों का लाभ उठा सकता है
मैंने इस बारे में स्टैकओवरफ्लो पर एक अलग सवाल पूछा है कि आप SIMD निर्देशों और उनके प्रदर्शन प्रभाव का उपयोग करते हुए कैसे प्रतिवर्ती समानता व्यक्त करेंगे: अस्थायी बिंदु समानता तुलना के लिए SIMD निर्देश
अद्यतन: ऐसा लगता है कि तीन SIMD निर्देशों का उपयोग करके कुशलतापूर्वक रिफ्लेक्सिव समानता को लागू करना संभव है।
Equals
फ़्लोटिंग पॉइंट को शामिल करते समय दस्तावेज़ के लिए संवेदनशीलता की आवश्यकता नहीं होती है:समान (ऑब्जेक्ट) विधि के सभी कार्यान्वयन के लिए निम्न कथन सही होना चाहिए। सूची में
x
,y
औरz
ऑब्जेक्ट संदर्भों का प्रतिनिधित्व करते हैं जो शून्य नहीं हैं।x.Equals(x)
रिटर्नtrue
, ऐसे मामलों को छोड़कर, जिनमें फ्लोटिंग-पॉइंट प्रकार शामिल हैं। आईएसओ / आईईसी / आईईईई 60559 देखें: 2011, सूचना प्रौद्योगिकी - माइक्रोप्रोसेसर सिस्टम - फ्लोटिंग-पॉइंट अंकगणित।यदि आप फ़्लोट्स का उपयोग कर रहे हैं, तो शब्दकोष कुंजियों के रूप में आप पाप की स्थिति में रह रहे हैं और समझदार व्यवहार की अपेक्षा नहीं करनी चाहिए।
प्रतिवर्त होने के तर्क:
यह सहित मौजूदा प्रकार, के साथ संगत है
Single
,Double
,Tuple
औरSystem.Numerics.Complex
।मैं बीसीएल में किसी भी मिसाल को नहीं जानता जहां
Equals
प्रतिवर्त होने के बजाय IEEE का अनुसरण करता है। काउंटर उदाहरणों में शामिल हैंSingle
,Double
,Tuple
औरSystem.Numerics.Complex
।Equals
ज्यादातर कंटेनरों और खोज एल्गोरिदम द्वारा उपयोग किया जाता है जो रिफ्लेक्सिटी पर भरोसा करते हैं। इन एल्गोरिदम के लिए एक प्रदर्शन लाभ अप्रासंगिक है अगर उन्हें काम करने से रोकता है। प्रदर्शन के लिए शुद्धता का त्याग न करें।- यह सब हैश आधारित सेट और शब्दकोशों टूट जाता है,
Contains
,Find
,IndexOf
विभिन्न संग्रहों / LINQ, सेट आधारित LINQ परिचालन (परUnion
,Except
आदि) यदि डेटा होता हैNaN
मानों। कोड जो वास्तविक गणना करता है जहां IEEE शब्दार्थ स्वीकार्य है आमतौर पर ठोस प्रकारों और
==
/!=
(या अधिक संभावना एप्सिलॉन तुलना) पर काम करता है ।आप वर्तमान में जेनेरिक का उपयोग करके उच्च प्रदर्शन संगणना नहीं लिख सकते क्योंकि आपको इसके लिए अंकगणितीय संचालन की आवश्यकता है, लेकिन ये इंटरफेस या वर्चुअल तरीकों के माध्यम से उपलब्ध नहीं हैं।
तो एक धीमी
Equals
विधि सबसे उच्च प्रदर्शन कोड को प्रभावित नहीं करेगा।यह एक
IeeeEquals
विधि याIeeeEqualityComparer<T>
उन मामलों के लिए प्रदान करना संभव है जहां आपको या तो IEEE शब्दार्थ की आवश्यकता होती है या आपको प्रदर्शन लाभ की आवश्यकता होती है।
मेरी राय में ये तर्क एक जोरदार कार्यान्वयन के पक्ष में हैं।
Microsoft की CoreFX टीम ने .NET में ऐसे वेक्टर प्रकार की शुरुआत करने की योजना बनाई है। मेरे विपरीत वे IEEE समाधान पसंद करते हैं , मुख्य रूप से प्रदर्शन लाभ के कारण। चूंकि इस तरह का निर्णय निश्चित रूप से एक अंतिम रिलीज के बाद नहीं बदला जाएगा, इसलिए मैं समुदाय से प्रतिक्रिया प्राप्त करना चाहता हूं, जिस पर मैं एक बड़ी गलती मानता हूं।
float
/ double
और कई अन्य प्रकारों के लिए, ==
और Equals
पहले से ही अलग हैं। मुझे लगता है कि मौजूदा प्रकारों के साथ एक विसंगति भी असंगतता के बीच की तुलना में अधिक भ्रामक होगी ==
और Equals
आपको अभी भी अन्य प्रकारों से निपटना होगा। 2) बहुत सारे जेनेरिक एल्गोरिदम / संग्रह उपयोग Equals
करते हैं और फ़ंक्शन (LINQ और शब्दकोशों) के लिए इसकी संवेदनशीलता पर भरोसा करते हैं, जबकि कंक्रीट फ्लोटिंग-पॉइंट एल्गोरिदम आमतौर पर ==
उनका IEEE शब्दार्थ प्राप्त करते हैं।
Vector<float>
एक साधारण float
या से अलग "जानवर" पर विचार करूंगा double
। उस उपाय से, मैं Equals
या ==
ऑपरेटर को उनके मानकों का पालन करने का कारण नहीं देख सकता। आपने खुद कहा: "यदि आप फ़्लोट्स का उपयोग कर रहे हैं तो शब्दकोश कुंजियों के रूप में आप पाप की स्थिति में रह रहे हैं और उन्हें समझदार व्यवहार की उम्मीद नहीं करनी चाहिए"। यदि कोई NaN
एक शब्दकोश में संग्रहित करता है, तो यह भयानक अभ्यास का उपयोग करने के लिए अपने स्वयं के ईश्वरीय दोष है। मुझे शायद ही लगता है कि CoreFX-team ने ऐसा नहीं सोचा था। मैं ReflexiveEquals
प्रदर्शन के लिए सिर्फ एक या समान के साथ जाऊँगा ।
==
औरEquals
विभिन्न परिणाम लौटाएगा। कई प्रोग्रामर मान वे कर रहे हैं, और कर एक ही बात । इसके अलावा - सामान्य तौर पर, समानता-ऑपरेटरों के कार्यान्वयनEquals
पद्धति को लागू करते हैं । आपने तर्क दिया है कि एक में एक शामिल हो सकता हैIeeeEquals
, लेकिन एक इसे दूसरे तरीके से भी कर सकता है और इसमें एकReflexiveEquals
एमथोड शामिल है ।Vector<float>
प्रकार में इस्तेमाल किया जा सकता कई प्रदर्शन महत्वपूर्ण अनुप्रयोगों, और उसके अनुसार अनुकूलित किया जाना चाहिए।