1

我只需要这样做:

编写一个重复程序,将计算以下语句 (n<10) 并显示计算结果 1+1/2!+1/3!.......+1/n!

我知道这是我必须做的一个阶乘,但是是倒置的 (^-1) 并且有一个条件,我是否必须包括浮点数或类似的东西?

#include <stdio.h>

int getValue()
{
    int n;

    printf("Enter number: ");
    scanf("%d%*c", &n);

    return(n);
}

int factorial(int n)
{
    int i, f;

    f = 1;
    for(i=1; i<=n; i++)
    f = f * i;

    return(f);
}

void printFactorial(int f)
{
    printf("The factorial is: %d", f);
}

int main()
{
    int f = getValue();

    factorial(f);
    printFactorial();

    return(0);
}
4

6 回答 6

3

对于 f=1+1/2!+1/3!.......+1/n!

无需使用阶乘

这个怎么样 ?

    double term=1.0;
    double f=1.0;

    for(i=2;i<=n;i++)
    {
     term*=1.0/i;
     f+=term;
    }
于 2013-08-15T10:36:03.893 回答
3

好吧,我探索了一些选择,即

简单的方法:

double sum = 1;
double fact = 1;
for (int i = 2; i <= n; i++)
{
    fact *= i;
    sum += 1 / fact;
}

卡汉总和:

double sum = 1;
double fact = 1;
double correction = 0;
for (int i = 2; i <= n; i++)
{
    fact *= i;
    double y = (1 / fact) - correction;
    double t = sum + y;
    correction = (t - sum) - y;
    sum = t;
}

有理数:

double numerator = 1;
double denominator = 1;
for (int i = 2; i <= n; i++)
{
    numerator = numerator * i + 1;
    denominator = denominator * i;
}
double result = numerator / denominator;

简单的方法和 Kahan Sum 给出了相同的结果。显然,阶乘驱动如此之快的倒数,以至于没有什么东西可以总结出任何后果n = 16

有理数给出的答案略有不同(准确度稍差),但在我的测试中要快一些。

于 2013-08-15T10:57:43.023 回答
1

你得到的大部分是正确的。并将类型声明f为双精度。

for(i=1; i<=n; i++) // Outer loop to make `n` number of summations
{
    for ( ... )     // Inner loop to calculate factorial of denominators
    {
       // factorial logic here
    }
    f = f + (double) (1/factorial result);
}

希望你的想法。

于 2013-08-15T10:17:13.627 回答
1

您需要计算 sum_(i=1)^(n) (1/(i!)) 对吗?

我会做一个 for 循环来总结所有有理数(需要双打)。每个 for 循环计算一个分母,然后进行除法 1/分母。

像那样:

f=0;
for(i=1;i<=n;i++)
{
    denominator = 1; // sorry initialized first time with zero...
    for(j=1;j<=i;j++) denominator *= j;
    f+= 1/(double)denominator;
}
于 2013-08-15T10:20:22.737 回答
0

你几乎得到了阶乘部分。只需要做

printFactorial(factorial(f));

但要达到“f=1+1/2!+1/3!.......+1/n!”,推荐递归解决方案。如果您首先对最小的派系项求和,您将获得更好的数值结果。

 #include <stdio.h>

double JAceHelper(double Factorial, int i, int n) {
  if (i >= n) {
    return 0.0;
    }
  i++;
  return 1/Factorial + JAceHelper(Factorial * i, i, n);
}

// For f=1+1/2!+1/3!.......+1/n!
double JAce(int n) {
  if (n < 0) return 1.0;  // error
  if (n < 1) return 1.0;
  return JAceHelper(1.0, 1, n);
}

int main() {
  int n;
  printf("Enter number: ");
  scanf("%d%*c", &n);
  printf("Sum is %20.15lf\n", JAce(n));
  return (0);
}
于 2013-08-16T03:28:28.100 回答
0

简单的解决方案使用浮点。

如果你想提高你的准确性,应该先把最小的项加在一起。我在其他地方发布了一个递归解决方案来执行此操作,但随后是一个简单的非递归解决方案,并与另一个流行的答案进行了比较。

将 2 种方法(使用 float)与使用 double(未显示)的相同方法进行比较以确定相对误差。“先求和最小项”从未被“先求最大项”打败。

注意:
1+1/2!+1/3!.......+1/n! = (( (((1/n + 1)/(n-1) + 1)/(n-2) + 1) ... )/2 + 1/1

float f1(int n) {  // sum smallest terms together first
  float sum = 0.0;
  while (n >= 1) {
    sum = (1.0f + sum) / n;
    n--;
  }
  return sum;
}

float f2(int n) { // sum largest terms together first
  float term = 1.0;
  float f = 1.0;
  int i;
  for (i = 2; i <= n; i++) {
    term *= 1.0f / i;
    f += term;
  }
  return f;
}

void ftest(int n) {
  double y = (d1(n) + d2(n))/2;  // d1,d2 is a double version of f1,f2 (not shown)
  printf("f1 %2d %.8e %+e\n", n, f1(n), (f1(n) - y)/y);
  printf("f2 %2d %.8e %+e\n", n, f2(n), (f2(n) - y)/y);
}

int main() {
  int i;
  for (i = 5; i < 9; i++)
    ftest(i);
  return 0;
}

f1  5 1.71666670e+00 +1.851795e-08  // The exact answer is 1.716666...
f2  5 1.71666658e+00 -5.092436e-08
f1  6 1.71805549e+00 -4.008979e-08
f2  6 1.71805549e+00 -4.008979e-08
f1  7 1.71825397e+00 +1.101240e-09
f2  7 1.71825385e+00 -6.827691e-08
f1  8 1.71827877e+00 -2.422694e-09
f2  8 1.71827865e+00 -7.179985e-08
于 2013-08-19T17:38:38.177 回答