0

所以我正在尝试解决这个问题:

问题

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

此外,有人告诉我,我应该期望给程序输入,例如:零 (0)、非常小 (0.00001) 和不那么小 (0.1)。

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

最后,有人告诉我程序的输入是一个小数 Epsilon。例如,您可以假设 0.00001f。

您不断添加无限级数,直到当前项的值低于 Epsilon。

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

到目前为止的代码

#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

因此,根据每个人的评论,并使用维基百科中的第 4 个“错位”方程式,就像我被告知的那样,这就是我想出的代码。我脑海中的逻辑似乎与大家所说的一致。但是输出根本不是我想要实现的。有没有人通过查看这段代码知道我可能做错了什么?

4

5 回答 5

2

Σ表示总和,因此您的等式意味着计算从 n=0 开始并趋向无穷大的项的总和:

在此处输入图像描述

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

在此处输入图像描述

计算的每次迭代都更准确地代表了实际值。 ε是一个误差项,表示迭代的变化小于 ε 量。

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

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。

编码:

do {
    last = sum;
    sum += 1/fact;
    fact *= ++n;
} while(sum-last >= e);
于 2012-10-08T01:56:29.113 回答
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;
}
于 2012-10-07T22:16:35.850 回答
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;
    }
}

但是如果你需要一个阶乘函数,我会推荐一个表格、记忆和伽玛函数,而不是天真的学生实现。如果您不知道这些是什么,请谷歌搜索。祝你好运。

于 2012-10-07T16:22:25.503 回答
1

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

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

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

于 2012-10-07T16:23:58.227 回答
1

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

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

在 MAIN 函数中:

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

在功能内:

  • 在 do-while 循环中:
    • 继续累加项直到 |Sn+1 - Sn| < 爱普生。
    • Sn 是前 n 项的总和。
    • Sn+1 是前 (n+1) 项的总和。当达到所需的精度 EPSILON 时,打印 SUM 和添加到总和的 TERMS 数。

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

于 2013-03-23T13:31:03.370 回答