MethodImplOptions.InternalCall
इसका मतलब है कि विधि वास्तव में, CLR में कार्यान्वित किया जाता सी में लिखे ++। इन-इन-टाइम कंपाइलर आंतरिक रूप से कार्यान्वित तरीकों के साथ एक तालिका का उपभोग करता है और कॉल को सी ++ फ़ंक्शन पर सीधे संकलित करता है।
कोड को देखने के लिए सीएलआर के लिए स्रोत कोड की आवश्यकता है। आप इसे SSCLI20 distribution से प्राप्त कर सकते हैं। यह .NET 2.0 टाइम फ्रेम के आसपास लिखा गया था, मुझे निम्न स्तर के कार्यान्वयन मिले हैं, जैसे Math.Pow()
सीएलआर के बाद के संस्करणों के लिए अभी भी काफी हद तक सटीक है।
लुकअप तालिका clr/src/vm/ecall.cpp में स्थित है। अनुभाग कि Math.Pow()
के लिए प्रासंगिक है इस तरह दिखता है:
FCFuncStart(gMathFuncs)
FCIntrinsic("Sin", COMDouble::Sin, CORINFO_INTRINSIC_Sin)
FCIntrinsic("Cos", COMDouble::Cos, CORINFO_INTRINSIC_Cos)
FCIntrinsic("Sqrt", COMDouble::Sqrt, CORINFO_INTRINSIC_Sqrt)
FCIntrinsic("Round", COMDouble::Round, CORINFO_INTRINSIC_Round)
FCIntrinsicSig("Abs", &gsig_SM_Flt_RetFlt, COMDouble::AbsFlt, CORINFO_INTRINSIC_Abs)
FCIntrinsicSig("Abs", &gsig_SM_Dbl_RetDbl, COMDouble::AbsDbl, CORINFO_INTRINSIC_Abs)
FCFuncElement("Exp", COMDouble::Exp)
FCFuncElement("Pow", COMDouble::Pow)
// etc..
FCFuncEnd()
"COMDouble" की खोज की पर ले जाता है clr/src/classlibnative/नाव/comfloat.cpp। मैं आपको कोड छोड़ दूंगा, बस अपने लिए एक नज़र डालें। यह मूल रूप से कोने के मामलों के लिए जांच करता है, फिर सीआरटी के pow()
के संस्करण को कॉल करता है।
एकमात्र अन्य कार्यान्वयन विवरण जो दिलचस्प है तालिका में FCIntrinsic मैक्रो है। यह एक संकेत है कि जिटर एक आंतरिक के रूप में कार्य को कार्यान्वित कर सकता है। दूसरे शब्दों में, फ़्लोटिंग पॉइंट मशीन कोड निर्देश के साथ फ़ंक्शन कॉल को प्रतिस्थापित करें। जो Pow()
के मामले में नहीं है, इसके लिए कोई एफपीयू निर्देश नहीं है। लेकिन निश्चित रूप से अन्य सरल संचालन के लिए। उल्लेखनीय है कि यह C++ में एक ही कोड की तुलना में सी # में फ्लोटिंग पॉइंट गणित को काफी तेज़ कर सकता है, कारण के लिए this answer देखें।
वैसे, यदि आपके पास Visual Studio vc/crt/src निर्देशिका का पूर्ण संस्करण है तो सीआरटी के लिए स्रोत कोड भी उपलब्ध है। आप दीवार को pow()
पर हिट करेंगे हालांकि, माइक्रोसॉफ्ट ने इंटेल से उस कोड को खरीदा था। इंटेल इंजीनियरों की तुलना में बेहतर काम करना असंभव है। हालांकि मेरी उच्च विद्यालय किताब की पहचान दोगुनी गति से था जब मैं इसे करने की कोशिश:
public static double FasterPow(double x, double y) {
return Math.Exp(y * Math.Log(x));
}
लेकिन एक सच्चे विकल्प है क्योंकि यह 3 से त्रुटि जम जाता है चल बिन्दु आपरेशनों और पागल डोमेन समस्याओं से निपटने के नहीं है कि पाउ () है। 0^0 और इंफिनिटी की तरह किसी भी शक्ति में उठाया गया।
बस एक एफवाईआई के रूप में, यदि आप 'बाहरी' मोडिफ़ायर के साथ पूरे 'आंतरिक कॉल' के बारे में उलझन में हैं (जैसे वे _seem_ विरोधाभासी होने के लिए), तो कृपया [प्रश्न (और परिणामी उत्तर)] देखें (http://stackoverflow.com/questions/1211462/c-sharp-internal-static-extern-with-internalcall-attribute-internal-or-externa) कि मैंने इस बारे में एक ही चीज़ पोस्ट की है। – CraigTP
'x^x' ऑपरेशन के लिए यदि' x' पूर्णांक है तो परिणाम एक शिफ्ट ऑपरेशन है। तो हो सकता है कि आप '2' के मंटिसा और' x' के एक्सपोनेंट का उपयोग करके परिणाम बना सकें। – ja72
@ सूरजजैन आपकी टिप्पणी वास्तव में एक प्रश्न है जिसे आपको अलग से पोस्ट करने की आवश्यकता है। – ja72