如何计算精度为 E=0.0001 的序列 e^(-x) 之和?
How to calculate a sum of sequence e^(-x) with accuracy E=0.0001?
所以我可以计算一个没有准确度 E 的序列和。
int t=1, x, k;
float sum, a, result, factorial=1, E=0.0001;
for(k=0;k<=(n);k++){
while(t<=n){
factorial*=t;
t++;
}
sum=(pow(-x,k))/factorial;
sum+=sum;
//while(fabs(sum-???)<E){
// result=sum;
//}
}
所以我知道序列的总和sum(k)。但是要准确计算 E,我必须知道前面元素的总和 sum(k-1) .如何从 for 循环 中得到 sum(k-1)?
对不起英语。
首先要注意您应用的幂公式:根据 wikipedia,您应该添加项 pow(-x,k)/(k!)
而不是 pow(-x,k)/(n!)
。
这会导致对您的代码进行小幅优化:因为 k! = k * (k-1)!
我们可以避免内部 while
循环和大量无用的乘法运算。
顺便说一下,求和的方法也有一个错误:你总是把前面的结果删掉,然后第二次加上当前项。
纠正后,您只需要处理一个额外的变量:
double myexpo(double x, int n=100) {
int k;
double sum = 1.0, pvsum, factorial = 1.0, E = 0.0001;
for (k = 1; k <= (n); k++){ // start with 1
pvsum = sum;
factorial *= k; // don't calculate factorial for 0.
sum += (pow(-x, k)) / factorial;
if (k > 1 && fabs(sum - pvsum) < E) { // check if diff is small enough
cout << k << " iterations" << endl;
break; // interupt the for loop if it's precise enough
}
}
return sum; // at the end of the loop sum is the best approximation
}
你可以用这个来测试这个功能:
double x;
do {
cout << "Enter number: ";
cin >> x;
cout << myexpo(x) << endl;
cout << exp(-x) << endl;
} while (x > 0);
备注: 我建议使用 double
或使用 f
后缀作为浮点数(例如0.001f),即使它按原样工作。
检查项的绝对值何时变得小于您期望的准确度。
double sum = 0, x = 1, k = 0, E = 0.0001, fact = 1;
while(true){
double term = pow(-x, k) / fact;
if(fabs(term) < E)
break;
sum += term;
fact *= (++k);
}
printf("e^(-x) = %.4f", sum);
这是 e ^ (-x) 的泰勒级数吗?如果是这样,你写错了。我不认为你得到的会收敛。
http://www.efunda.com/math/taylor_series/exponential.cfm
e ^ (-x) 是 1 + (-x) + (-x)^2/2! + (-x)^3/3! + ...
double calculate_power_of_e(double xx, double accuracy) {
double sum(1.0);
double term(1.0);
for (long kk=1; true; ++kk) {
term *= (-xx) / kk;
sum += term;
if (fabs(term) < accuracy)
break;
}
return sum;
}
printf("e^(-x)" = %.4f\n", calculate_power_of_e(5.0, .0001));
当术语与 1.0 相比微不足道时,停止循环。
通过递归,|x|
不是太大,先求和最小的项。
e(x) = 1 + x/1! + x*x/2! + x*x*x/3! + ...
double my_exp_term(double x, double term, unsigned n) {
if (term + 1.0 == 1.0) return term;
n++;
return term + my_exp_term(x, term*x/n, n);
}
double my_exp(double x) {
return 1.0 + my_exp_term(x, x, 1);
}
double y = my_exp(-1);
所以我可以计算一个没有准确度 E 的序列和。
int t=1, x, k;
float sum, a, result, factorial=1, E=0.0001;
for(k=0;k<=(n);k++){
while(t<=n){
factorial*=t;
t++;
}
sum=(pow(-x,k))/factorial;
sum+=sum;
//while(fabs(sum-???)<E){
// result=sum;
//}
}
所以我知道序列的总和sum(k)。但是要准确计算 E,我必须知道前面元素的总和 sum(k-1) .如何从 for 循环 中得到 sum(k-1)? 对不起英语。
首先要注意您应用的幂公式:根据 wikipedia,您应该添加项 pow(-x,k)/(k!)
而不是 pow(-x,k)/(n!)
。
这会导致对您的代码进行小幅优化:因为 k! = k * (k-1)!
我们可以避免内部 while
循环和大量无用的乘法运算。
顺便说一下,求和的方法也有一个错误:你总是把前面的结果删掉,然后第二次加上当前项。
纠正后,您只需要处理一个额外的变量:
double myexpo(double x, int n=100) {
int k;
double sum = 1.0, pvsum, factorial = 1.0, E = 0.0001;
for (k = 1; k <= (n); k++){ // start with 1
pvsum = sum;
factorial *= k; // don't calculate factorial for 0.
sum += (pow(-x, k)) / factorial;
if (k > 1 && fabs(sum - pvsum) < E) { // check if diff is small enough
cout << k << " iterations" << endl;
break; // interupt the for loop if it's precise enough
}
}
return sum; // at the end of the loop sum is the best approximation
}
你可以用这个来测试这个功能:
double x;
do {
cout << "Enter number: ";
cin >> x;
cout << myexpo(x) << endl;
cout << exp(-x) << endl;
} while (x > 0);
备注: 我建议使用 double
或使用 f
后缀作为浮点数(例如0.001f),即使它按原样工作。
检查项的绝对值何时变得小于您期望的准确度。
double sum = 0, x = 1, k = 0, E = 0.0001, fact = 1;
while(true){
double term = pow(-x, k) / fact;
if(fabs(term) < E)
break;
sum += term;
fact *= (++k);
}
printf("e^(-x) = %.4f", sum);
这是 e ^ (-x) 的泰勒级数吗?如果是这样,你写错了。我不认为你得到的会收敛。
http://www.efunda.com/math/taylor_series/exponential.cfm
e ^ (-x) 是 1 + (-x) + (-x)^2/2! + (-x)^3/3! + ...
double calculate_power_of_e(double xx, double accuracy) {
double sum(1.0);
double term(1.0);
for (long kk=1; true; ++kk) {
term *= (-xx) / kk;
sum += term;
if (fabs(term) < accuracy)
break;
}
return sum;
}
printf("e^(-x)" = %.4f\n", calculate_power_of_e(5.0, .0001));
当术语与 1.0 相比微不足道时,停止循环。
通过递归,|x|
不是太大,先求和最小的项。
e(x) = 1 + x/1! + x*x/2! + x*x*x/3! + ...
double my_exp_term(double x, double term, unsigned n) {
if (term + 1.0 == 1.0) return term;
n++;
return term + my_exp_term(x, term*x/n, n);
}
double my_exp(double x) {
return 1.0 + my_exp_term(x, x, 1);
}
double y = my_exp(-1);