我正在制作使用遞回和非遞回函式列印 1 到 20 數字的 n 次方的程式。我想為用戶提供一個輸入實數的選項。怎么做?可以不用pow函式嗎?感謝您的幫助!
uj5u.com熱心網友回復:
如果你想把一個數字提高到一個實指數 x
a^x
你可以把它計算為
e^(x ln a)
所以你可以寫一個函式
double mypow( double base, double exponent )
{
return exp( exponent * log( base ) )
}
如果你想深入研究并創建你自己的expand實作log,你可以使用泰勒級數
e^x = 1 x ((x^2)/2!) ((x^3)/3!) ...
和
ln x = 2( u (u^3)/3 (u^5)/5 ... ), u = (x 1)/(x-1)
就個人而言,我只會使用該pow功能。
uj5u.com熱心網友回復:
在制作時double keiski_pow(double num, double exponent)考慮特定條件下的不同代碼。
// exponent == 0, num != 0
return 1
// exponent == 0, num == 0
Domain error
// num > 0
return exp(log(num)*exponent)
// or more accurately
return exp2(log2(num)*exponent)
// num == 0, exponent < 0
Infinity
// num < 0, exponent is an integer > 0.
// Integer test for `double`: trunc(exponent) == exponent
t = keiski_pow(num, exponent/2)
return t*t*(exponent%2 ? num : 1)
// or
t = keiski_pow(fabs(num), exponent)
return t*exponent%2 ? -1 : 1)
// num < 0, exponent is an integer < 0
return 1.0/keiski_pow(num, -exponent)
// num < 0, exponent is not an integer
Domain error
我認為這涵蓋了大多數情況。(NaN 是另一個故事)
注:recursion()是非常非常緩慢的大exponent。試試recursion(1.0, 1e15)。
一個更快的遞回解決方案:
double recursion_alt(double num, double exponent) {
// Code only valid when exponent has a whole number value
assert(exponent = trunc(exponent));
if (exponent > 0.0) {
double exponent_mod2 = fmod(exponent, 2.0);
double exponent_div2 = (exponent - exponent_mod2)/2.0;
double t = recursion_alt(num, exponent_div2);
return t*t*(exponent_mod2 ? num : 1.0);
}
if (exponent < 0.0) {
return 1.0/recursion_alt(num, -exponent);
}
return 1.0;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/363244.html
