我在C中编写了一个程序,用于计算函数exp(x)在x的各种值的近似值,有些是正数,有些是负数。我的问题如下:
感谢您的贡献。我感谢任何帮助和建议。
P.S:我在64位硬件上使用GCC编译,但在32位Ubuntu 12.04 LTS(a.k.a Precise Pangolin)上编译。
#include <stdio.h>
#include <math.h>
//We need to write a factorial function beforehand, since we
//have factorial in the denominators.
//Remembering that factorials are defined for integers; it is
//possible to define factorials of non-integer numbers using
//Gamma Function but we will omit that.
//We first declare the factorial function as follows:
long double factorial (double);
//Long long integer format only allows numbers in the order of 10^18 so
//we shall use the sign bit in order to increase our range.
//Now we define it,
long double
factorial(double n)
{
//Here s is the free parameter which is increased by one in each step and
//pro is the initial product and by setting pro to be 0 we also cover the
//case of zero factorial.
int s = 1;
long double pro = 1;
if (n < 0)
printf("Factorial is not defined for a negative number \n");
else {
while (n >= s) {
pro *= s;
s++;
}
return pro;
}
}
int main ()
{
long double x[13] = { 1, 5, 10, 15, 20, 50, 100, -1, -5, -10, -20, -50, -100};
//Here an array named "calc" is defined to store
//the values of x.
//The upper index controls the accuracy of the Taylor Series, so
//it is suitable to make it an adjustable parameter. However, after
//a certain value of p the series become infinitely large to be
//represented by the computer; hence we terminate the series at
//the 151th term.
int p = 150;
long double series[13][p];
int i, k;
//We only define the Taylor series for positive values of the exponent, and
//later we will use these values to calculate the reciprocals. This is done
//in this manner to avoid the ambiguity introduced into the sum due to terms
//alternating in sign.
long double sum[6] = { 0 };
for (i = 0; i <= 6;i++) {
for (k = 0; k <= p; k++){
series[i][k] = pow(x[i], k)/( factorial(k));
sum[i] += series[i][k];
}
printf("Approximation for x = %Lf is %Lf \n", x[i], sum[i]);
}
//For negative numbers -taking into account first negative number is
//in the 8th position in the x array and still denoting the approximation
long double approx[5] = { 0 };
for (i = 7; i <= 12;i++) {
approx[i - 7] = 1 / sum[i - 7];
printf("Approximation for x = %Lf is %Lf \n", x[i], approx[i - 7]);
}
//printf("%Lf \n", factorial(3));
//The above line was introduced to test if the factorial function
//was functioning properly.
}
答案 0 :(得分:2)
回答你的一些问题。
1我的日食代码没有爆炸。
2除了可能过多的迭代之外,我认为使用for循环没有固有的低效率。
3使用"%Le"
作为科学格式。
4您可以获得的最大精度将是LDBL_EPSILON 1.取决于您不知道的系统(可能是1个功率(2,64))。记住精度是相对的,而不是绝对的。
5分段错误可能是由于approx[5]
造成的。 @Grijesh Chauhan
建议
将-15
添加到long double x[13+1] = { 1, 5, 10, 15, 20, 50, 100, -1, -5, -10, -15, -20, -50, -100 };
。更改其他各种13
s。
添加返回错误条件:
if (n < 0) { printf("Factorial is not defined for a negative number \n"); return 0; }
更改为long double approx[5+1+1] = { 0 };
添加返回main()
。
如果您首先添加小条款,则会获得更好的数值结果。这通常意味着撤消for (k = 0; k <= p; k++)
循环。
int main() {
long double x[13+1] = { 1, 5, 10, 15, 20, 50, 100, -1, -5, -10, -15, -20, -50, -100 };
int p = 150;
long double series[13+1][p];
int i, k;
long double sum[6+1] = { 0 };
for (i = 0; i <= 6; i++) {
for (k = 0; k <= p; k++) {
series[i][k] = pow(x[i], k) / (factorial(k));
sum[i] += series[i][k];
}
printf("Approximation for x = %Le is %Le %e\n", x[i], sum[i], exp(x[i]));
}
long double approx[7] = { 0 };
for (i = 7; i <= 12; i++) {
approx[i - 7] = 1 / sum[i - 7];
printf("Approximation for x = %Le is %Le %e\n", x[i], approx[i - 7], exp(x[i]));
}
return 0;
}