如何在C中的无穷级数中近似e

时间:2012-10-07 16:16:46

标签: c math loops recursion infinite

所以我试图解决这个问题:

Problem

但是,我不完全确定从哪里开始或者我到底要找什么。

另外,我被告知我应该给程序输入如:零(0),非常小(0.00001),而不是那么小(0.1)。

我得到了这个:http://en.wikipedia.org/wiki/E_%28mathematical_constant%29作为参考,但该公式看起来与问题中的公式不完全相同。

最后,我被告知程序的输入是一个小数字Epsilon。例如,您可以假设为0.00001f。

你继续添加无限系列直到当前术语的值低于Epsilon。

但总而言之,我不知道这意味着什么。我有点理解维基上的等式。但是,我不知道从哪里开始解决问题。看看它,有没有人知道我应该在C中使用什么样的公式以及“E”是什么以及它在这里发挥作用(即在公式中,我理解它假设是用户输入)。 / p>

代码到目前为止

#include <stdio.h>
#include <math.h>

//Program that takes in multiple dates and determines the earliest one
int main(void)
{
    float e = 0;
    float s = 0;
    float ct = 1;
    float ot= 1;
    int n = 0;
    float i = 0;
    float den = 0;
    int count = 0;

    printf("Enter a value for E: ");
    scanf("%f", &e);

    printf("The value of e is: %f", e);


    for(n = 0; ct > e; n++)
    {
        count++;
            printf("The value of the current term is: %f", ct);

        printf("In here %d\n", count);

        den = 0;

        for(i = n; i > 0; i--)
        {
            den *= i;
        }

        //If the old term is one (meaning the very first term), then just set that to the current term
        if (ot= 1)
        {
            ct = ot - (1.0/den);
        }
        //If n is even, add the term as per the rules of the formula
        else if (n%2 == 0)
        {
            ct = ot + (1.0/den);
            ot = ct;
        }
        //Else if n is odd, subtract the term as per the rules of the formula
        else
        {
            ct = ot - (1.0/den);
            ot = ct;
        }

        //If the current term becomes less than epsilon (the user input), printout the value and break from the loop
        if (ct < epsilon)
        {
            printf("%f is less than %f",ct ,e);
            break;
        }
    }

    return 0;
}

当前输出

Enter a value for E: .00001
The value of e is: 0.000010
The value of the current term is: 1.000000
In here 1
-1.#INF00 is less than 0.000010

因此,基于每个人的评论,并使用维基百科的第四个“紊乱”等式,就像我被告知的那样,这是我提出的代码。我脑子里的逻辑似乎与每个人都说的一致。但输出完全不是我想要达到的目标。有没有人有任何想法,从这个代码看我可能做错了什么?

5 个答案:

答案 0 :(得分:2)

Σ代表一个总和,所以你的等式意味着计算从n = 0开始到无穷远的术语之和:

enter image description here

符号n!表示“阶乘”,它是数字1到n的乘积:

enter image description here

计算的每次迭代更准确地表示实际值。 ε是一个错误术语,意味着迭代的变化小于ε量。

要开始计算互动,您需要一些起始条件:

unsigned int n = 0; // Iteration.  Start with n=0;
double fact = 1;    // 0! = 1.  Keep running product of iteration numbers for factorial.
double sum = 0;     // Starting summation.  Keep a running sum of terms.
double last;        // Sum of previous iteration for computing e
double e;           // epsilon value for deciding when done.

然后算法很简单:

  1. 存储上一笔款项。
  2. 计算下一笔款项。
  3. 更新n并计算下一个阶乘。
  4. 检查新旧迭代的差异是否超过epsilon。
  5. 代码:

    do {
        last = sum;
        sum += 1/fact;
        fact *= ++n;
    } while(sum-last >= e);
    

答案 1 :(得分:1)

该求和符号为您提供线索:您需要一个循环。

什么是0!? 1,当然。所以你的e起始值是1.

接下来,你将写一个n的循环,从1到更大的值(无穷大可能暗示一个while循环),你计算每个连续的项,看它的大小是否超过你的epsilon,并将它加到e的总和。

如果您的条款小于epsilon,请停止循环。

暂时不要担心用户输入。让你的功能工作。硬编码epsilon,看看你改变它会发生什么。保留最后一位的输入。

你需要一个好的阶乘功能。 (不是真的 - 感谢Mat提醒我。)

你问过常数e来自何处?而这个系列?该系列是指数函数的泰勒级数展开式。请参阅任何介绍微积分文本。常数e很简单,指数函数为指数1。

我有一个很好的Java版本在这里工作,但我会避免发布它。它看起来就像C函数一样,所以我不想放弃它。

更新:既然你已经展示了你的,我会告诉你我的:

package cruft;

/**
 * MathConstant uses infinite series to calculate constants (e.g. Euler)
 * @author Michael
 * @link
 * @since 10/7/12 12:24 PM
 */
public class MathConstant {

    public static void main(String[] args) {
        double epsilon = 1.0e-25;
        System.out.println(String.format("e = %40.35f", e(epsilon)));
    }

    // value should be 2.71828182845904523536028747135266249775724709369995
    //          e =    2.718281828459045
    public static double e(double epsilon) {
        double euler = 1.0;
        double term = 1.0;
        int n = 1;
        while (term > epsilon) {
            term /= n++;
            euler += term;
        }
        return euler;
    }
}

但是如果你需要一个阶乘函数,我会推荐一个表格,memoization和gamma函数,而不是幼稚的学生实现。如果你不知道那些是什么,谷歌的那些。祝你好运。

答案 2 :(得分:1)

你需要编写一个开始的C程序。互联网上有很多来源,包括如何从argc和argv变量获取用户输入。如果没有输入,看起来你要使用0.00001f作为epsilon。 (在尝试让程序接受输入之前,使用它来使程序工作。)

对于计算系列,您将使用循环和一些变量:sum,current_term和n。在每次循环迭代中,使用n计算current_term,递增n,检查当前项是否小于epsilon,如果不是,则将current_term添加到总和中。

这里要避免的最大缺陷是错误地计算整数除法。例如,您将要避免使用像1 / n这样的表达式。如果要使用这样的表达式,请改用1.0 / n。

答案 3 :(得分:1)

实际上这个程序非常类似于Deitel在C语言学习中给出的程序,现在到了这一点(错误不能为0因为e是一个无理数,所以不能精确计算)我这里有一个对你非常有用的代码。

#include <stdio.h>


/* Function Prototypes*/
long double eulerCalculator( float error, signed long int *iterations );
signed long int factorial( int j );


/* The main body of the program */
int main( void ) 
{
    /*Variable declaration*/
    float error;
    signed long int iterations = 1;

    printf( "Max Epsilon admited: " );
    scanf( "%f", &error );
    printf( "\n The Euler calculated is: %f\n", eulerCalculator( error, &iterations ) ); 
    printf( "\n The last calculated fraction is: %f\n", factorial( iterations ) );
    return 1;
}


long double eulerCalculator( float error, signed long int *iterations ) 
{
    /* We declare the variables*/
    long double n, ecalc;


    /* We initialize result and e constant*/
    ecalc = 1; 

    /* While the error is higher than than the calcualted different keep the loop */
    do {

        n = ( ( long double ) ( 1.0 / factorial( *iterations ) ) );
        ecalc += n;
        ++*iterations;

    } while ( error < n );


    return ecalc;
}

signed long int factorial( signed long int j )
{
    signed long int b = j - 1;

    for (; b > 1; b--){
        j *= b;
    }

    return j;
}

答案 4 :(得分:1)

编写MAIN函数和FUNCTION来计算以下系列的近似和。

            (n!)/(2n+1)!  (from n=1 to infinity)

在MAIN功能中:

  • 从中读取类型为DOUBLE(所需精度)的变量EPSILON      标准输入。      EPSILON是一个极小的正数,小于或等于      到10 ^( - 6)。
  • EPSILON值将作为参数传递给FUNCTION。

在FUNCTION中:

  • 在do-while循环中:
    • 继续添加条款,直到| Sn + 1 - Sn | &LT; EPSILON。
    • Sn是前n个项的总和。
    • Sn + 1是第一个(n + 1)-terms的总和。 达到所需的精度EPSILON时,打印SUM和数字 将TERMS添加到总和中。

使用不同的EPSILON值(从10 ^( - 6)到10 ^( - 12))测试程序 一次一个。