तीन आत्म कार्यान्वित कार्यों iPow(x, n)
, Ln(x)
और Exp(x)
का उपयोग करना, मैं गणना करने के लिए fPow(x, a)
, एक्स और एक जा रहा है युगल में सक्षम हूँ। नीचे दिए गए कार्यों में से कोई भी लाइब्रेरी फ़ंक्शंस का उपयोग नहीं करता है, लेकिन केवल पुनरावृत्ति। कार्यान्वित कार्यों के बारे में
कुछ स्पष्टीकरण:
(1) iPow(x, n)
: एक्स double
है, एन int
है। यह एक साधारण पुनरावृत्ति है, क्योंकि एन एक पूर्णांक है।
(2) Ln(x)
: यह फ़ंक्शन टेलर श्रृंखला पुनरावृत्ति का उपयोग करता है। पुनरावृत्ति में उपयोग की जाने वाली श्रृंखला Σ (from int i = 0 to n) {(1/(2 * i + 1)) * ((x - 1)/(x + 1))^(2 * n + 1)}
है। प्रतीक ^
पावर फ़ंक्शन Pow(x, n)
को पहला फ़ंक्शन में कार्यान्वित करता है, जो सरल पुनरावृत्ति का उपयोग करता है।
(3) Exp(x)
: यह फ़ंक्शन, टेलर सीरीज़ पुनरावृत्ति का उपयोग करता है। पुनरावृत्ति में उपयोग की जाने वाली श्रृंखला Σ (from int i = 0 to n) {x^i/i!}
है। यहां, ^
पावर फ़ंक्शन को इंगित करता है, लेकिन यह पहला Pow(x, n)
फ़ंक्शन कॉल करके गणना की गई है; इसके बजाय इसे d *= x/i
का उपयोग करके, तीसरे फ़ंक्शन के भीतर, तथ्यात्मक के साथ समवर्ती रूप से लागू किया गया है। मुझे लगता है कि मुझे इस चाल का उपयोग का उपयोग करना था, क्योंकि इस फ़ंक्शन में, पुनरावृत्ति अन्य कार्यों के सापेक्ष कुछ और कदम उठाती है और अधिकांश समय के फैक्टरियल (i!)
ओवरफ़्लो होती है। यह सुनिश्चित करने के लिए कि पुनरावृत्ति खत्म नहीं हो पाती है, इस भाग में पावर फ़ंक्शन एक साथ फैक्टोरियल के साथ पुनरावृत्त होता है। इस तरह, मैंने ओवरफ्लो को पार कर लिया।
(4) fPow(x, a)
: x और एक दोनों युगल हैं। यह फ़ंक्शन कुछ भी नहीं करता है बल्कि ऊपर लागू अन्य तीन कार्यों को कॉल करता है। इस फ़ंक्शन में मुख्य विचार कुछ कैलकुलेशन पर निर्भर करता है: fPow(x, a) = Exp(a * Ln(x))
। और अब, मेरे पास सभी कार्यों iPow
, Ln
और Exp
पहले से ही पुनरावृत्ति के साथ हैं।
एनबी। मैंने पुनरावृत्ति को रोकने के लिए कौन सा कदम तय करने के लिए constant MAX_DELTA_DOUBLE
का उपयोग किया था। मैंने इसे 1.0E-15
पर सेट कर दिया है, जो कि युगल के लिए उचित लगता है। इसलिए, अगर (delta < MAX_DELTA_DOUBLE)
पर पुनरावृत्ति बंद हो जाती है, तो आपको long double
का उपयोग कर सकते हैं और MAX_DELTA_DOUBLE
के लिए निरंतर मान घटा सकते हैं, उदाहरण के लिए 1.0E-18
(1.0E-18 न्यूनतम होगा)।
यहां कोड है, जो मेरे लिए काम करता है।
#define MAX_DELTA_DOUBLE 1.0E-15
#define EULERS_NUMBER 2.718281828459045
double MathAbs_Double (double x) {
return ((x >= 0) ? x : -x);
}
int MathAbs_Int (int x) {
return ((x >= 0) ? x : -x);
}
double MathPow_Double_Int(double x, int n) {
double ret;
if ((x == 1.0) || (n == 1)) {
ret = x;
} else if (n < 0) {
ret = 1.0/MathPow_Double_Int(x, -n);
} else {
ret = 1.0;
while (n--) {
ret *= x;
}
}
return (ret);
}
double MathLn_Double(double x) {
double ret = 0.0, d;
if (x > 0) {
int n = 0;
do {
int a = 2 * n + 1;
d = (1.0/a) * MathPow_Double_Int((x - 1)/(x + 1), a);
ret += d;
n++;
} while (MathAbs_Double(d) > MAX_DELTA_DOUBLE);
} else {
printf("\nerror: x < 0 in ln(x)\n");
exit(-1);
}
return (ret * 2);
}
double MathExp_Double(double x) {
double ret;
if (x == 1.0) {
ret = EULERS_NUMBER;
} else if (x < 0) {
ret = 1.0/MathExp_Double(-x);
} else {
int n = 2;
double d;
ret = 1.0 + x;
do {
d = x;
for (int i = 2; i <= n; i++) {
d *= x/i;
}
ret += d;
n++;
} while (d > MAX_DELTA_DOUBLE);
}
return (ret);
}
double MathPow_Double_Double(double x, double a) {
double ret;
if ((x == 1.0) || (a == 1.0)) {
ret = x;
} else if (a < 0) {
ret = 1.0/MathPow_Double_Double(x, -a);
} else {
ret = MathExp_Double(a * MathLn_Double(x));
}
return (ret);
}
क्या आप वास्तविक दुनिया प्रोसेसर पर उपलब्ध सुविधाओं के संदर्भ में कार्यान्वित करना चाहते हैं - अधिकांश में हार्डवेयर निर्देश के रूप में एक्सप (एक्स) के कुछ रूप शामिल हैं, इसलिए पाउ को एक्सपी और एलएन के संदर्भ में लागू किया गया है - या कुछ के संदर्भ में मशीन जिसमें इनकी कमी है? यदि उत्तरार्द्ध, वांछित निर्देश सेट का वर्णन करें। –
यह जांचें http://www.queryhome.com/27195/how-to-write-your-own-pow-function-in-c – user2794034
संभावित डुप्लिकेट [मनमानी शक्ति/रूट की गणना कैसे करें?] (Http: //stackoverflow.com/questions/1375953/how-to-calculate-an-arbitrary-power-root) – jww