计算1+的和;(1/2!)+…+;C语言中的(1/n!)n数字

计算1+的和;(1/2!)+…+;C语言中的(1/n!)n数字,c,algorithm,C,Algorithm,就像标题所说的,我如何计算n个数的和的形式:1+(1/2!)+⋯(1/n!)?我已经得到了谐波系列的代码: #include <stdio.h> int main( void ) { int v=0,i,ch; double x=0.; printf("Introduce un número paracalcular la suma: "); while(scanf("%d",&v)==0 || v<=0) {

就像标题所说的,我如何计算n个数的和的形式:1+(1/2!)+⋯(1/n!)?我已经得到了谐波系列的代码:

#include <stdio.h>

int main( void )
{
    int v=0,i,ch;
    double x=0.;

    printf("Introduce un número paracalcular la suma: ");
    while(scanf("%d",&v)==0 || v<=0)
    {
        printf("Favor de introducir numeros reales positivos: ");
        while((ch=getchar())!='\n')
            if(ch==EOF)
                return 1;
    }
    for (i=v; i>=1; i--)
        x+=1./i;

    printf("EL valor de la serie es %f\n", x);
    getch();
    return 0;
}
#包括
内部主(空)
{
int v=0,i,ch;
双x=0。;
printf(“介绍unnúmero paracalcularla suma:”);
而(scanf(“%d”,&v)==0 | | v=1;i--)
x+=1./i;
printf(“系列产品价格%f\n”,x);
getch();
返回0;
}
这里的问题是。。我已经得到了作为分数的和,但是如何使变量“I”成为阶乘呢


注意:我正在用C语言编程,使用DEV-C++4.9.9.2

如果您只是想计算前n个阶乘,我建议您只需递归计算它们,例如

factorial[0] = 1;
for (i = 1; i < n; i++) factorial[i] = factorial[i-1] * i;
factorial[0]=1;
对于(i=1;i

但是,除非将它们存储为浮点数,否则大阶乘将很快溢出。

对于调和求和1./i+1./(i-1)。。。1./1. 我建议你继续按那个顺序做

[编辑]重写:感谢@pablo197指出了我的错误

要计算谐波和1+(1/2!)+…+(1/n!),请先将最低有效项相加,这样有助于将精度损失降至最低。从最低有效项
1/n
开始为
sum
,该项与n-1项之和为:
sum=(1+sum)/(n-1)
,依此类推。(见下文)

添加
1.0
1/0
one\u over\u factorial\u系列
,关于
e=2.7182818284…

[编辑]详细信息,显示如何直接n!避免了计算

1 + (1/2!) + … + (1/n!) =  
1/n!  +  1/((n-1)!)   +  1/((n-2)!)  +  1/((n-3)!)  + ... + 1 =  
(1/n + 1)/((n-1)!)    +  1/((n-2)!)  +  1/((n-3)!)  + ... + 1 =  
((1/n + 1)/(n-1) + 1)/((n-2)!)       +  1/((n-3)!)  + ... + 1 =  
...
((((1/n + 1)/(n-1) + 1)/(n-2) + 1)/(n-3) + 1)/(n-4) + ... =  

数字n!等于n和前面阶乘的乘积,即(n-1)
如果你计算n!在一次迭代中,您正在执行n个产品。
在下一步中,假设n+1,您再次重复这n个乘积,然后再乘以n+1。
这意味着您正在一次又一次地重复相同的操作

更好的策略是保持在步骤n中计算的前一个阶乘,然后在步骤n+1中,仅乘以n!n+1。这将每次迭代中的产品数量减少到1个

因此,可以按以下方式计算序列:

 int max_n = 20;     /* This value can come from another point of the program */

 int n;                  /* Initial value of the index */
 double factorial_n = 1; /* It has to be initialized to 1, since the factorial of 0 is 1 */
 double sum = 0.0;       /* It has to be initialized to 0, in order to calculate the series */

 for (n = 0; n <= max_n; )
  {
      sum += 1.0/factorial_n;
      n++;
      factorial_n *= n;
  }

 printf("Series result: %.20f\n", sum);
int max_n=20;/*该值可以来自程序的另一个点*/
int n;/*索引的初始值*/
双阶乘n=1;/*它必须初始化为1,因为0的阶乘是1*/
双和=0.0;/*必须将其初始化为0才能计算序列*/

对于(n=0;n在这种情况下计算阶乘是不好的,因为它会导致n的小值溢出。使用以下伪代码将其放入
O(n)
中而不溢出

double sum = 0.0;
double acc = 1;
double error = 0.0000001;

for(i=1;i<=n;i++) {
   acc = acc/i;
   if(acc<error)
       break;
   sum = sum + acc; 
}

print(sum);

注意:-因为上面的方法是反向构建的,所以它更精确,但不幸的是,因为它是O(N),所以更耗时即使对于更高的值,由于阶乘函数增长非常快,因此精度的提高也可以忽略不计,因此误差持续快速减小。

垂直选项卡?请…为阶乘创建一个函数。如何从1..N生成一个系列?使用它来将
1!
的项设置为
N!
但只需将其倒置即可。这就是思考阶乘的含义,然后写一个函数来完成它。然后输入i.@KerrekSB exp(1)是ans if n->infinity因此小n的精度损失,如5-1:OP问题是关于指数级数的。您的代码有一个从未使用过的伪阶乘计算,最终结果是谐波级数,OP已经解决了。@pablo1977对。Face palm-需要重新工作。我省略了我的dow请注意,因为您现在获得了正确的结果,但我一点也不相信。您的解决方案对我来说不太清楚。@pablo1977添加了一些细节,说明“1+(1/2!)+…+(1/n!)”如何更改为“(((1/n+1)/(n-1)+1)/(n-2)+1/(n-3)+1/(n-4)+…”。好的。我喜欢您的想法。首先,我不相信它,因为它“抽象地”很好,但在实践中可能会因分段累积误差而失去准确性。然而,我比较了您的版本和我的版本,两者给出了完全相同的结果(关于
中的
exp(1)
)。关于效率,您的算法的运算次数似乎与我的相同(n*(1减量+1除法+1和+1赋值))。但是,我发现“在数组中存储阶乘”技术的速度更快.我无法解释差异,但它似乎并不重要。这与其说是一个递归解决方案,不如说是一个动态规划解决方案。然而,该算法快速而准确。@pablo1977 factorial将溢出较大的值,并给出不可预测的值,为什么不除以数字,而至少乘以较高的值呢e 0,不会产生副作用。@Vikramhat:我避免在每次迭代中被j除,因为这会带来数值问题。另一方面,整数的乘积是精确的,正如您所指出的,只需注意溢出。我认为溢出处理将使我的论述变得模糊。不过,有一点评论可以添加。@pablo1977,由于您应用的模糊处理导致算法既不快速也不准确,我坚持认为这是一种糟糕的编码练习。打代码高尔夫很少会提高执行速度,但通常会降低试图理解代码的人的脑速。@Richard:“很少”不适用于我的代码,因为它的速度和准确性取决于“操作”的方式。我可以接受你对“风格”的批评,但你判断速度和准确性是错误的,因为你没有对问题进行必要的数学分析
#include <stdio.h> 

#define MAX_N 100

double factorial[MAX_N+1]; 

void build_factorials(double *factorial, int max)
{
    factorial[0] = 1.0;
    for (int j = 0;  j <= max; )
     {
       j++;
       factorial[j] = factorial[j-1] * j;
     }
}

double exp_series(int n)
{
    int j;
    double sum;
    if (n > MAX_N)  /* Error */
       return 0.0;

    sum = 0.0;   
    for (j = n; j >= 0; j--)
       sum += 1.0/factorial[j];
    return sum;
}

int main(void) 
{

 int n; 
 double sum; 

  build_factorials(factorial, MAX_N);

  printf("Series (up to n == 11): %.20f\n", exp_series(11));
  printf("Series (up to n == 17): %.20f\n", exp_series(17));
  printf("Series (up to n == 9):  %.20f\n", exp_series(9));

  getchar();    
}
double sum = 0.0;
double acc = 1;
double error = 0.0000001;

for(i=1;i<=n;i++) {
   acc = acc/i;
   if(acc<error)
       break;
   sum = sum + acc; 
}

print(sum);
double sum = 0.0;
double acc = 1;

for(i=n;i>=1;i--) {

   sum = (sum + 1)/i;
}

print(sum);