Calculation of M power of T: (exploring the implementation of C ++'s function POW (), combining mathematics with programming)
Source program download: http://pjy.studio.googlepages.com/powP.cpp
Or download it to my favorites.
Since C ++ has just finished learning the function chapter and needs to use the POW () function for exercises, I am wondering if I can write a function that can implement the POW () function, after some efforts, some results are produced.
As we all know, POW (double T, double m) is a function provided by C ++ to calculate the Power Y of X. Although the system provides this POW (), but I still want to write my own POW (). However, it may not be easy to write this pow, because the exponential M requires a double value, that is, it can be a decimal number, which is not a simple loop.
When I first thought about this problem, the first idea was to separate the integer and fractional parts of Y. For example, if M = 12.34, convert x ^ 12.34 to (x ^ 12) * (x ^ 34)/(x ^ 100). In this way, the case where the exponent is double is converted into the case where the three exponent is int. Take the integer, the simplest method may be int (Y), and use M-int (m) to decimal places, and then separate the decimal places as in the example. However, there may be two problems:
1. INT (y) may cause unexpected results, such as data loss.
2. It is troublesome to divide a floating point into three parts.
The above two points, coupled with my estimation that C ++ is unlikely to use this method, should start with the mathematical method, so I will find another way. It is also a coincidence that my mathematical analysis course has just completed the chapter of idempotence, and I have the idea of starting from the direction of t ^ m to the power series, here is an example in the book:
According to the knowledge of Power Series, when-1 <x <1, n-> infinity (n is an integer), the constant is: (1 + x) ^ m = 1 + mx + .... [m-1 )*.. * (m-n + 1) * (x ^ n)]/(n !) +...
(The proof is not listed)
And the general term is recorded as tmpm, that is, tmpm (n) = [m * (S-1 )*.. * (m-n + 1) * (x ^ n)]/(n !)
Since-1 <x <1, this method can only calculate 0 ~ The m power of 2, but if 1 + x> = 2, you can convert it to the-m power of 1/(1 + x. In conclusion, we can find the m power of a positive number t (t ^ m is regarded as (1 + x) ^ m ). It is estimated that the c ++ pow may also be implemented using a similar method.
From the formula, we need to first require x ^ n, that is, the integer power of a number, which is not difficult:
Double pow_ I (double num, int n) // calculate the n power of num, where n is an integer
{
Double powint = 1;
Int I;
For (I = 1; I <= n; I ++) powint * = num;
Return powint;
}
Then, we need another request, n! .
Finally, you can write the computing expansion function:
Double pow_f (double num, double m) // calculate the m power of num. num and m can be dual precision. num is greater than zero.
{
Int I, j;
Double powf = 0, x, tmpm = 1;
X = num-1;
For (I = 1; tmpm> 1e-12 | tmpm <-1e-12; I ++) // when tmpm is out of the range, stop the loop. The range can be changed.
{
For (j = 1, tmpm = 1; j <= I; j ++)
Tmpm * = (m-j + 1) * x/j;
Powf + = tmpm;
}
Return powf + 1;
}
Note that I did not use pow_ I () or a function to calculate the tmpm corresponding to each n !. Instead, it is directly written as tmpm * = (m-j + 1) * x/j, and the corresponding tmpm of n is obtained by repeating this formula. There is a reason for this:
1. This is more concise.
2. If the function returns n! The result of a loop of only 171 times is displayed, because 171! The value of double is exceeded. This may result in poor result accuracy due to insufficient loops, and may cause errors during running.
By now, pow_f can be used to determine that the base number is no greater than 2 and the exponent is the power of the real number. It is easy to think that, when the base number t> = 2, you can convert it to the-m power of 1/(1 + x. In theory, however, the machine actually shows a problem, that is, when t is relatively small (<1) and m is large, the error is very large, which may be caused by insufficient loops. That is to say, this pow_f cannot find the exact value of t <1, m> 1. In this case, it cannot find the value of t> 2, because after converting 1/t, it becomes a power problem to calculate the base number less than 1.
How can we solve this problem? In this case, m becomes a problem because t is small and m is large. In this case, we may split m into integers and decimals (marked as mi and mf respectively ), do you need to calculate the power of t and multiply the two results? For t ^ mi, you can use pow_ I (), for t ^ mf, you can use pow_f, in this case, mf <1 and pow_f is used to calculate t ^ mf. The result is very accurate. If this problem is solved, the problem t> = 2 is also solved.
Finally, there is another problem, that is, what to do with t <0. Here, my processing is: when t <0 is, if the index m is an integer, we will use pow_ I for the result, if m is not an integer, 0 (c ++'s pow () is returned as if it was an error. However, I am a beginner and didn't learn it, so I should return 0 ).
To sum up the above, we also need a function to serve as the entry, before calling pow_ I and pow_f to handle these situations:
Double pow_ff (double num, double m) // call pow_f () and pow_ I () to calculate the m power of num, which is the entry to calculate the power
{
If (num = 0 & M! = 0) return 0; // If num is 0, 0 is returned.
Else if (num = 0 & M = 0) return 1; // If num and m are both 0, 1 is returned.
Else if (Num <0 & M-int (m )! = 0) return 0; // If num is negative and M is not an integer, an error occurs and 0 is returned.
If (Num> 2) // convert the case where the base number is greater than 2 to (1/num) ^-M Calculation
{
Num = 1/num;
M =-m;
}
If (M <0) return 1/pow_ff (Num,-m); // convert an index smaller than 0 to 1/num ^-M.
If (m-int (m) = 0) return pow_ I (Num, m);/* When the exponent is a floating point number, divide it into integers and decimal places to calculate
Power. This is because the base number is small, and power is directly obtained using pow_f.
The error is large. Therefore, pow_ I is used for the integer part of the index, which is small.
Calculate the number using pow_f .*/
Else return pow_f (Num, M-int (M) * pow_ I (Num, INT (m ));
Return pow_f (Num, M );
}
In this way, the pow_ff is basically similar to the POW of C ++. It is unclear whether the system's pow is implemented in this way. This exercise made me feel the beauty of combining mathematics with programming, ^ _ ^.
Finally, since I was a beginner (I didn't even learn arrays at the time of study), errors are inevitable and the Code may not be very good. If you have any comments, questions, or better methods, very welcome to tell me: pjy.studio@gmail.com
(I am particularly grateful to Baidu for his advice on dividing m into mi and mf. At that time, I thought about this problem for a long time, but I couldn't think of this method when I was dull)
The source code is as follows:
//////////////////////////////////////// //// // Use your own function to implement c + + pow () features //// make beginner Pu Junyi /// level Limited, error is inevitable, welcome to exchange, If you have any comments, /// please email to: pjy.studio@gmail.com Thank you! //////////////////////////////////////// /// // # Include <iostream> # include <cmath> using namespace std; double pow_ I (double num, int n); // calculate the n power of num, where n is an integer double pow_f (double num, double m ); // calculate the m power of num. num and m can be dual precision. num is greater than zero and less than 2 double pow_ff (double num, double m); // call pow_f () and pow_ I (), calculate the m power of num, is the entry to calculate the power; int main () {double num, m; cout <"input base number num and index m: "<endl; cin> num> m; cout <" c ++'s answ Er: "<pow (num, m) <endl; cout <" my answer: "<pow_ff (num, m) <endl ;} double pow_ I (double num, int n) // calculate the n power of num, where n is an integer {double powint = 1; int I; for (I = 1; I <= n; I ++) powint * = num; return powint;} double pow_f (double num, double m) // calculate the m power of num, num and m can be double precision, num is greater than zero {int I, j; double powf = 0, x, tmpm = 1; x = num-1; for (I = 1; tmpm> 1e-12 | tmpm <-1e-12; I ++) // when tmpm is out of the next range, stop the loop. The range can be changed to {for (j = 1, tmpm = 1; j <= I; j ++) tmpm * = (m-j + 1) * x/j; Powf + = tmpm;} return powf + 1;} double pow_ff (double num, double m) // call pow_f () and pow_ I () to calculate the m power of num, is the entry for Power Calculation {if (num = 0 & m! = 0) return 0; // if num is 0, return 0 else if (num = 0 & m = 0) return 1; // if num and m are both 0, 1 else if (num <0 & m-int (m) is returned )! = 0) return 0; // if num is negative and m is not an integer, an error occurs. 0 if (num> 2) is returned) // convert the case where the base number is greater than 2 to (1/num) ^-m calculation {num = 1/num; m =-m;} if (m <0) return 1/pow_ff (num,-m); // convert the case where the index is smaller than 0 to 1/num ^-m for if (m-int (m) = 0) return pow_ I (num, m);/* When the exponent is a floating point number, divide it into integers and decimals to calculate the power respectively. This is because the base number is small, and the power error is obtained directly using pow_f, therefore, pow_ I is used for the integer part of the index, and pow_f is used for the fractional part. */else return pow_f (num, m-int (m) * pow_ I (num, int (m); return pow_f (num, m );}