我需要输入这个等式,其中有一个因子.我想知道是否有类似*=乘法或pow(1,3)的东西用于C中的因子.
term = pow(-1, K) * pow(x, 2K)/(2K)
Run Code Online (Sandbox Code Playgroud)
阶乘将是最后2K.
您很少需要计算阶乘的函数.因子增长得如此之快,以至于查找表对于计算不会溢出的少数值就足够了.如果要在循环中计算术语,则可以避免在整个术语中使用累加器计算阶乘.
K = 0;
term = 1;
while (K<N) {
/* use term */
do_something_with(term);
/* update term for new value of K */
K += 1;
term = -term * x*x / (2*K*(2*K-1));
}
Run Code Online (Sandbox Code Playgroud)
如果你似乎不清楚这一点,你可以先得到累积器是显式的程序,然后将更新步骤组合成一个如上所述的变量.这个程序仍然存在因子计算爆炸的问题.
K = 0;
pow_minus_1_K = 1;
pow_x_2K = 1;
factorial_2K = 1;
while (K<N) {
/* compute term */
term = pow_minus_1_K * pow_x_2K/factorial_2K;
/* update accumulators for new value of K */
K += 1;
pow_minus_1_K = -pow_minus_1_K;
pow_x_2K *= x*x;
factorial_2K *= 2*K*(2*K-1);
}
Run Code Online (Sandbox Code Playgroud)
毕竟,因子易于计算!只是n之前所有数字的乘积.但是有一个实际问题:因子很快就会溢出.一个32位的int可以容纳12 !,一个64位的int 20!
根据系列的收敛方式,您可能会溢出有效范围.
对于像你这样的近似系列,通常最好通过术语k-1找到表示术语k的方法.在你的情况下:
term = pow(-1, k) * pow(x, 2*k) / fact(2*k)
Run Code Online (Sandbox Code Playgroud)
你可以代表一个术语
term[k + 1] = -term[k] * pow(x, 2) / ((2*k - 1) * (2*k - 2))
Run Code Online (Sandbox Code Playgroud)
你的系列变成了:
double f(double x)
{
double term = 1.0;
double res = term;
int k = 0;
while (k < 100) {
double old = res;
term = -term * (x / (2*k + 1)) * (x / (2*k + 2));
res += term;
if (res == old) break;
k++;
}
return res;
}
Run Code Online (Sandbox Code Playgroud)
此函数最多使用100次迭代来计算余弦.当术语对结果没有贡献时,它会停止.在实践中,它通过大约10次迭代达到结果,因此在这种情况下,常规因子计算将足够准确.尽管如此,一遍又一遍地计算它们都是浪费.