public class exp {
public static void main(final String args[]) {
int i, numTerms = 10;
double fac, exp = 0.0;
for (i = 0, fac = 1.0; i < numTerms; i++, fac *= i) {
exp += 1.0/fac;
}
System.out.println("exp(1) = "+exp);
System.out.println("Error is "+Math.abs(Math.E-exp));
}
}
我是Java的新手,我想澄清一下此循环的工作原理。该循环应该将指数近似为1的幂:
如果我输入numTerms = 0,它会给我exp(1)= 0。是吗因为此循环不添加任何内容,所以给了我0?怎么样0确切地得出?
如果我输入numTerms = 1,它会给我expr(1)= 1。以来第一次迭代:i = 1,然后fac = 1,然后exp = 0 + 1/1 = 1。对吧?
如果我输入numTerms = 2,它会给我exp(1)= 2。为什么?由我逻辑,通过第二次迭代,i = 2,fac = 1 * 2 = 2,然后exp = 1 + 1/2 = 3/2。
我犯了什么错误?
而且,将fac和exp初始化为0.0的意义是什么? (代码的第三行)
整个代码是一种计算数学常数e
(自然对数的基数)的数值方法,但是您已经知道了。
for循环的语法允许声明多个变量,但是它们必须是同一类型。这就是在循环之前声明i
和fac
的原因。double fac, exp = 0.0;
语句声明两个变量,但仅初始化exp
,与int i...
类似。
使用任何数值方法得出的计算精度严格取决于步骤的数量(在这种情况下,是给定的迭代次数)。如果步数不足,则计算出的值可能会非常不准确(或者就像生成numTerms=0
或numTerms=1
的情况一样-完全错误的输出)。
您是正确的0。
对于numTerms=1
,它为1,因为对于第一次迭代,i
等于0,所以fac
初始化为1.0
。在代码块之后计算fac*=i
。
对于numTerms=2
:如果i
达到2,则循环条件为假:
i < numTerms - 2 < 2 <- which is false
[当循环条件为假时,则不执行它的块。i++, fac *= i
部分可能令人困惑,但是for循环如下所示:
for(initialization;condition;increment/update)
在开始之前,它会进行初始化(如果有变量),然后检查条件(变量可能已经超出条件限制)。如果条件为true,则调用代码块。在代码块之后,将调用increment/update
表达式,然后在运行代码块之前,它将再次检查条件。这样就可以了:
第一次迭代:i = 0,fac = 1-> exp + = 1/1 => exp = 1第二次迭代:i = 1,fac = 1-> exp + = 1/1 => exp = 2
在第二次迭代之后,将对“更新”表达式进行求值,使得:i = 2,fac = 2-但对于i=2
,循环条件为假。
我不太理解“如何精确得出0?”从您的问题,但我希望我已经回答了:)
也许是一个有趣的事实。您已经问过i
和fac
的初始化,实际上是在for循环中发生的。但可以这样做:
int i = 0, numTerms = 2; //the i is not only declared but also initialized here
double fac = 1.0, exp = 0.0; //same with fac
for (;i < numTerms; ++i, fac *= i) //so no need to do it again in for
for循环可以重写为while,反之亦然。写入for(;;)
与while(true)
相同。