Объяснение l oop, которое вычисляет экспоненту через сумму - PullRequest
0 голосов
/ 08 февраля 2020
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, и я хотел бы уточнить, как работает этот l oop. Предполагается, что l oop приближает экспоненту к степени 1:

enter image description here

Если я наберу для numTerms = 0 , это дает мне, что exp (1) = 0. Это потому, что этот l oop ничего не добавляет, поэтому он дает мне 0? Как точно получается 0?

Если я наберу для numTerms = 1, это даст мне expr (1) = 1. Начиная с первой итерации: i = 1, затем fac = 1, а затем exp = 0 + 1/1 = 1. Правильно?

Если я наберу numTerms = 2, это даст мне exp (1) = 2. Почему? По моим логам c, по второй итерации, i = 2, fac = 1 * 2 = 2, а затем exp = 1 + 1/2 = 3/2.

В чем ошибка Я делаю?

Кроме того, какой смысл инициализировать fa c и exp равным 0,0? (3-я строка кода)

1 Ответ

1 голос
/ 08 февраля 2020

Весь этот код представляет собой численный метод вычисления математической константы e (основание натурального логарифма), но вы уже знаете, что.

Синтаксис для l oop позволяет объявлять несколько переменных , но они должны быть одного типа.
Вот почему i и fac были объявлены до l oop.
. 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, условие l oop ложно:

i < numTerms     -     2 < 2     <- which is false

Если условие l oop ложно, то оно не не выполняет его блок.
Часть i++, fac *= i может сбивать с толку, но для l oop выглядит так:

for(initialization;condition;increment/update)

Перед запуском идет инициализация (если есть переменные), затем он проверяет условие (переменная уже может превышать ограничение в условии). Если условие истинно, вызывается кодовый блок.
После кодового блока вызываются выражения increment/update, затем перед запуском кодового блока он снова проверяет условие.
То есть go:

1-я итерация: i = 0, fac = 1 -> exp + = 1/1 => exp = 1
2-я итерация: i = 1, fac = 1 -> exp + = 1/1 => exp = 2

После 2-й итерации выражения "update" оцениваются следующим образом: i = 2, fac = 2 - но для i=2 условие l oop является ложным.

Я не совсем понимаю, "Как точно получается 0?" из ваших вопросов, но я надеюсь, что я уже ответил на него :)

И, возможно, интересный факт. Вы спрашивали там об инициализации i и fac, где это на самом деле происходит в течение l oop. Но это можно сделать:

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

Значение l oop можно переписать в while и наоборот.
Запись for(;;) такая же, как while(true).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...