2013-05-22 9 views
13

यह देखने के बाद कि double.Nan == double.NaN सी # में हमेशा झूठा रहता है, मैं उत्सुक हो गया कि हुड के तहत समानता कैसे लागू की गई थी। तो मैं डबल struct डिकंपाइल करने के लिए Resharper इस्तेमाल किया, और यहाँ मैं क्या पाया है:एक सिस्टम कब होता है। डबल नहीं है?

public struct Double : IComparable, IFormattable, IConvertible, IComparable<double>, IEquatable<double> 
{ 
    // stuff removed... 

    public const double NaN = double.NaN; 

    // more stuff removed... 
} 

यह हालांकि मैं, struct Double एक निरंतर है कि इस विशेष लोअर केस double के संदर्भ में परिभाषित किया गया है वाणी में इंगित करता है डी हमेशा सोचा था कि दोनों पूरी तरह से समानार्थी थे। और क्या है, अगर मैं लोअरकेस डबल पर कार्यान्वयन के लिए जाता हूं, तो रिशेर्पर बस फ़ाइल के शीर्ष पर घोषणा के लिए मुझे स्क्रॉल करता है। इसी प्रकार, लोअरकेस के NaN के कार्यान्वयन के लिए कूदने से पहले मुझे लाइन में पहले निरंतर घोषणा में ले जाता है!

तो मैं इस प्रतीत होता है कि यह प्रतीत होता है कि यह पुनरावर्ती परिभाषा है। क्या यह सिर्फ डिकंपेलर का एक आर्टेफैक्ट है? शायद Resharper में एक सीमा? या क्या यह लोअरकेस डबल वास्तव में एक अलग जानवर है - सीएलआर/सीटीएस से निचले स्तर पर कुछ का प्रतिनिधित्व करता है?

NaN कहां से आता है?

+2

क्या इससे संबंधित है? http://stackoverflow.com/questions/4751885/how-are-the-primitive-types-defined-non-recursively और http://stackoverflow.com/questions/16113850/if-int32-is-just-an -alias-for-int-how-can-the-int32-class-use-an-int –

+3

मेटाडेटा को देखने के लिए बस VS का उपयोग करना 'सार्वजनिक कॉन्स डबल NaN = 0.0/0.0; ' –

+1

' NaN' का अर्थ है 'नहीं संख्या' और 'इन्फिनिटी' की तरह सकारात्मक या नकारात्मक हो सकती है। अगर कोई सोच रहा है। – Nolonar

उत्तर

8

.NET असेंबली के लिए अब तक का सबसे अच्छा स्रोत वास्तविक स्रोत कोड है जिसका उपयोग उन्हें बनाने के लिए किया गया था। सटीकता के लिए किसी भी डिकंपेलर को मारता है, टिप्पणियां भी काफी उपयोगी हो सकती हैं। Reference Source डाउनलोड करें।

आप यह भी देखेंगे कि Double.NaN आईएल में मार्क के रूप में परिभाषित नहीं है, यह वास्तव में सी # स्रोत कोड फ़ाइल में है।

public const double NaN = (double)0.0/(double)0.0; 

कौन सी # संकलन समय पर निरंतर भाव का मूल्यांकन संकलक का लाभ लेता है: net/clr/bcl/system/double.cs स्रोत कोड फ़ाइल असली घोषणा को दर्शाता है। या इसे जीभ-इन-गाल डालने के लिए, NaN को C++ कंपाइलर द्वारा परिभाषित किया गया है क्योंकि वह भाषा है जिसे सी # कंपाइलर लिखने के लिए उपयोग किया गया था;)

15

डिकंपील्ड कोड को देखने से सावधान रहें, खासकर यदि यह कुछ अंतर्निहित है। वास्तविक आईएल यहाँ (.NET 4.5 के लिए, कम से कम) है:

.field public static literal float64 NaN = float64(NaN) 
{ 
    .custom instance void __DynamicallyInvokableAttribute::.ctor() 
} 

यानी यह NaN टोकन के माध्यम से आईएल में सीधे नियंत्रित किया जाता है।

हालांकि, क्योंकि यह const (literal आईएल में) है, तो इसे कॉल साइट में "जला दिया जाएगा"; double.NaN का उपयोग करने वाले कहीं भी float64(NaN) का उपयोग कर रहे हैं। इसी तरह, उदाहरण के लिए, अगर मैं कार्य करें:

const int I = 2; 
int i = I; 
int j = 2; 

इन असाइनमेंट के दोनों समान अंतिम आईएल में दिखेगा (वे दोनों हो जाएगा ldc.i4.2)।

इस वजह से, अधिकांश डीकंपलर आईएल पैटर्न NaN को पहचानेंगे और double.NaN के समतुल्य भाषा के साथ इसका प्रतिनिधित्व करेंगे। लेकिन इसका मतलब यह नहीं है कि कोड स्वयं रिकर्सिव है; वे शायद सिर्फ एक जांच नहीं है "लेकिन क्या यह डबल है। नैन खुद?"। आखिरकार, यह केवल एक विशेष मामला है, जहां float64(NaN) आईएल में एक मान्यता प्राप्त मूल्य है।

[__DynamicallyInvokable] 
public const double NaN = (double) 1.0/(double) 0.0; 

फिर से मतलब नहीं है कि यह सच है:: p केवल कि यह कुछ है जो एक ही अंतिम परिणाम हो सकता है

संयोग से, परावर्तक के रूप में यह decompiles।

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