2011-02-08 12 views
10

मैं सिस्टम का उपयोग कर रहा हूं। काफी हाल ही में बहुत कुछ और दूसरे दिन मैं सोच रहा था कि माइक्रोसॉफ्ट पुस्तकालय में एसकर्ट विधि को कैसे लागू करेगा। तो मैं अपना सर्वश्रेष्ठ दोस्त परावर्तक खुला पॉप और पुस्तकालय में विधि डिसअसेंबल करने की कोशिश की है, लेकिन यह पता चला है:सी # Math.Sqrt कार्यान्वयन

[MethodImpl(MethodImplOptions.InternalCall),ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] 
public static extern double Sqrt(double d); 

उस दिन पहली बार के लिए कभी, मुझे एहसास हुआ कि कैसे निर्भर अपने बच्चों ढांचे पर कर रहे हैं, खाने के लिए ।

चुटकुले अलग-अलग, लेकिन मैं सोच रहा था कि इस विधि को लागू करने के लिए किस तरह के एल्गोरिदम एमएस का उपयोग किया जाएगा या दूसरे शब्दों में यदि आप कोई लाइब्रेरी समर्थन नहीं रखते हैं तो आप सी # में Math.Sqrt का अपना कार्यान्वयन कैसे लिखेंगे।

चीयर्स

+6

ब्याज से, हमारे सर्वोत्तम साथी को मार्च के रूप में 35 डॉलर की लागत होगी ... – StuartLC

उत्तर

17

कोई भी तरीका जो आप प्रतिबिंबक या संदर्भ स्रोत के साथ वापस पाते हैं जिसमें MethodImplOptions.InternalCall विशेषता वास्तव में सीएलआर के अंदर सी ++ में लागू की जाती है। आप एसएससीएलआई 20 वितरण से इनके लिए स्रोत कोड प्राप्त कर सकते हैं। प्रासंगिक फ़ाइल clr/src/vm/ecall.cpp है, इसमें फ़ंक्शन पॉइंटर्स के साथ विधि नामों की एक तालिका है, जो जेआईटी कंपाइलर द्वारा जेनरेट किए गए मशीन कोड में सीधे कॉल पता एम्बेड करने के लिए उपयोग की जाती है। प्रासंगिक तालिका अनुभाग

FCIntrinsic("Cos", COMDouble::Cos, CORINFO_INTRINSIC_Cos) 
FCIntrinsic("Sqrt", COMDouble::Sqrt, CORINFO_INTRINSIC_Sqrt) 
FCIntrinsic("Round", COMDouble::Round, CORINFO_INTRINSIC_Round) 
... 

जो तुम clr/src/classlibnative/फ्लोट करने के लिए ले जाता है/comfloat.cpp

FCIMPL1_V(double, COMDouble::Sqrt, double d) 
    WRAPPER_CONTRACT; 
    STATIC_CONTRACT_SO_TOLERANT; 

    return (double) sqrt(d); 
FCIMPLEND 

यह सिर्फ CRT फ़ंक्शन को कॉल है। लेकिन यह नहीं है कि x86 जिटर में क्या होता है, तालिका घोषणा में 'आंतरिक' नोट करें। आपको यह नहीं मिलेगा कि जिटर के एसएसएलआई 20 संस्करण में, यह पेटेंट द्वारा अनगिनत एक साधारण है। शिपिंग एक तथापि इसे चालू करता है एक आंतरिक में:

 double d = 2.0; 
     Console.WriteLine(Math.Sqrt(d)); 

00000008 fld   dword ptr ds:[0072156Ch] 
0000000e fsqrt 
..etc 

करने के लिए अनुवाद दूसरे शब्दों में, Math.Sqrt() एक भी चल बिन्दु मशीन कोड निर्देश के लिए अनुवाद। this answer पर यह जांच के लिए कि कैसे देशी कोड को आसानी से धड़कता है।

+0

एचएसएनएस, गहन उत्तर के लिए बहुत धन्यवाद। – Raghu

4

फ़ंक्शन का संयोजन असेंबलर निर्देशों में किया जाएगा। जैसे x12 के fsqrt निर्देश।

आप सॉफ़्टवेयर में फ़्लोटिंग पॉइंट नंबर लागू कर सकते हैं, लेकिन यह अधिक धीमा हो जाएगा। मुझे लगता है कि एसक्यूआरटी के लिए सामान्य कार्यान्वयन एक पुनरावृत्त एल्गोरिदम है।

2

Google.com आप से StackOverflow.com

इस पेज पर एक नज़र डालें अधिक जवाब दे देंगे: उपरोक्त में http://en.wikipedia.org/wiki/Methods_of_computing_square_roots एक एल्गोरिथ्म शीर्षक के अंतर्गत पाया जा सकता है "बाइनरी अंक प्रणाली (आधार 2)" विकी पेज।

लेकिन, सॉफ्टवेयर कार्यान्वयन कुशल नहीं होंगे। आधुनिक सीपीयू के पास एफपीयू में गणित कार्यों के लिए हार्डवेयर कार्यान्वयन हैं। तुम बस

+0

यह अभी भी सॉफ़्टवेयर है, भले ही यह हार्डवेयर में संग्रहीत है और माइक्रो-प्रोग्राम कहलाता है। –

1
public double Sqrt(int number) 
{ 
    double x = number/2; 

    for (int i = 0; i < 100; i++) x = (x + number/x)/2d; 

    return x; 
} 

बहुत कच्चे तेल की विधि (विधानसभा या मशीन भाषा में) प्रोसेसर का सही निर्देश को लागू करने की जरूरत है लेकिन इस तरह के तरीके के रूप में लॉग करता है, तो मैं कुछ प्रयोग किया जाता है और अधिक विस्तृत है, तो आप पूछ सकते "और मैं कैसे लागू कर सकते लॉग विधि? "

+0

मुझे यकीन नहीं है कि क्या कम से कम महत्वपूर्ण बिट्स सही होंगे। – CodesInChaos

+0

ठीक है, ज़ाहिर है। यही कारण है कि मैंने कहा कि यह बहुत 'क्रूड' है, बेशक, आप त्रुटि के पर्याप्त मार्जिन तक पहुंचने के लिए कई बार फिर से शुरू कर सकते हैं, लेकिन इससे एल्गोरिदम कम पठनीय हो जाएगा। '2 डी'' 2' 'डबल' के रूप में है। –

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