试图近似自然对数e的值和用于计算e的项的使用次数

时间:2012-10-09 05:09:14

标签: java algorithm approximation

package homework1C;

public class Homework1C {

public static void main(String[] args){
    double term =2,sum;
    int n;
    final double difference = 0.0000000001;
    double x;
    for(sum=0.0,n=0;term > difference;n++){


        x = find_n_fact(n);
        term=1.0/x;
         sum+=term;
         n++;
    }

        System.out.printf("e : %f\n", sum);
        System.out.printf("term : %d\n", n);

    }

public static int find_n_fact(int n){
int i;
int fact = 2;
for(i = n; i>2;i--){

    fact *= i;
}
    return fact;
}

}

这就是我被要求做的事情: 编写另一个Java应用程序来查找并显示e(自然对数)的近似值。使用以n为2开始的以下近似公式,递增1,直到e的两个连续值相差小于0.0000000001,并且不仅显示近似值,而且显示在最后一次近似中使用了多少个n项。公式为:近似e = 1/0! + 1/1! + 1/2! + 1/3! + ...,其中n!是n阶乘

这是我此计划的现有输出

e : 1.043081
term : 20
我在做错了什么?答案是假设是

e: 2.71828
term: 15

如何解决这个问题?

3 个答案:

答案 0 :(得分:0)

当n为0或1时,看起来你的因子函数find_n_fact不正确。

答案 1 :(得分:0)

你做过几个错误:

  • 您的析法方法错了。虽然可以按照您尝试的迭代方式完成,但我建议您使用递归版
  • 你在main()的for循环中递增n两次,这是无稽之谈。

以下是适合您的完整代码:

public class Homework1C {
    public static void main(String[] args) {
        double term = 2, sum = 0;
        final double difference = 0.0000000001;
        int n;

        for (n = 0; term > difference; n++) {
            term = 1.0 / find_n_fact(n);
            sum += term;
        }

        System.out.printf("e : %f\n", sum);
        System.out.printf("term : %d\n", n);
    }

    public static double find_n_fact(int n) {

        if (n == 0 || n == 1)
            return 1.0;

        return n * find_n_fact(n - 1);
    }
}

析法方法的迭代版本在这里:

public static double find_n_fact(int n) {
    double i, fact = 1;

    if(n < 0) // for negative numbers, factorial is nonsense.
        return -1;

    for (i = n; i > 1; i--)
        fact *= i;

    return fact;
}

答案 2 :(得分:0)

总之,1/n!后面的术语是1/(n+1)!。这意味着没有理由重新开始(从头开始计算(n+1)!),而只是将当前术语值除以下一个n值;即循环内容只需

    term /= n;
    sum += term;

在循环开始之前将n,term和sum初始化为1(因为1/0!为1)。当然,将n++取出循环,因为for语句本身包含n++。这种方法摆脱了find_n_fact()函数及其中的错误。 (次要注意:1e-100.0000000001写起来更方便,并且具有相同的值。)还有一个建议:添加类似

的语句
System.out.printf("sum : %12.10f   term: %12.10f  1/t: %12.10f,  n: %d\n", sum, term, 1/term, n);
调试时在循环内部

;这会使额外n++之类的错误和阶乘函数中的错误变得明显。