Страница 1 из 3

Рассчитать значение функции с использованием циклов while или do while

Добавлено: 02 ноя 2017, 00:26
alexboliam
Здраствуйте, сейчас прохожу тему с итерационными циклами, надо написать программу, которая "рассчитает с точностью до 6 цифр значение функции Lnx. Сравнить полученное с помощью ряда значение со значением , полученным стандартной функцией."

Вопросы таковы: как задать рассчет до n-ой цифры?(вроде что-то через %, но не уверен)
Как написать именно эту функцию? Чтобы перед непарным членом стоял знак "+", а перед парным "-".
И последнее, через какой цикл все оформить?
Спасибо за внимание!

Re: Рассчитать значение функции с использованием циклов while или do while

Добавлено: 02 ноя 2017, 01:26
Absurd
alexboliam писал(а):Здраствуйте, сейчас прохожу тему с итерационными циклами, надо написать программу, которая "рассчитает с точностью до 6 цифр значение функции Lnx. Сравнить полученное с помощью ряда значение со значением , полученным стандартной функцией."
Это сходящаяся последовательность. Каждый член меньше предыдущего не в разы, а на порядок. Это значит что когда N-ный член на порядок меньше 1e-6, то сумма всего остального от N до +Inf на шестой разряд повлиять заведомо уже не сможет, иначе ряд не был бы сходящимся.
alexboliam писал(а): Как написать именно эту функцию? Чтобы перед непарным членом стоял знак "+", а перед парным "-".
(N%2)*2 - 1 Даст -1 для четных N, и 1 для нечетных (остаток от деления на два даст 1 для нечетных, и 0 для четных. Это уможается на два чтобы 1 отобразить на 2 а ноль - на ноль. Потом вычитаем единичку чтобы получить -1 для четных и 1 - для нечетных). Если член умножить на эту величину, то он будет либо положительным, либо отрицательным. Модуль от умножения на единичку не изменится.
alexboliam писал(а): И последнее, через какой цикл все оформить?
Да без разницы, все циклы эквивалентны. Можно написать программу любой сложности пользуясь только for. Или только while. Разница только в удобстве и наглядности для каждого конкретного слячая.

Re: Рассчитать значение функции с использованием циклов while или do while

Добавлено: 02 ноя 2017, 01:44
alexboliam
Absurd писал(а):Это сходящаяся последовательность. Каждый член меньше предыдущего не в разы, а на порядок. Это значит что когда N-ный член на порядок меньше 1e-6, то сумма всего остального от N до +Inf на шестой разряд повлиять заведомо уже не сможет, иначе ряд не был бы сходящимся.


(N%2)*2 - 1 Даст -1 для четных N, и 1 для нечетных (остаток от деления на два даст 1 для нечетных, и 0 для четных. Это уможается на два чтобы 1 отобразить на 2 а ноль - на ноль. Потом вычитаем единичку чтобы получить -1 для четных и 1 - для нечетных). Если член умножить на эту величину, то он будет либо положительным, либо отрицательным. Модуль от умножения на единичку не изменится.


Да без разницы, все циклы эквивалентны. Можно написать программу любой сложности пользуясь только for. Или только while. Разница только в удобстве и наглядности для каждого конкретного слячая.

Спасибо за ответ! Я сначала думал, что последовательность задается как сумма (см. вложение). Но все же не могу понять, как это записать на C++.

Re: Рассчитать значение функции с использованием циклов while или do while

Добавлено: 02 ноя 2017, 02:00
Absurd
alexboliam писал(а):Спасибо за ответ! Я сначала думал, что последовательность задается как сумма (см. вложение). Но все же не могу понять, как это записать на C++.

Ну очевидно что нужно накапливать результат в какой-то переменной-аккумуляторе. Если накапливается результат умножения, начальное значение аккумулятора должно быть 1.0. Для суммы начальный элемент - 0.0. Сначала к аккумулятору, который вначале равен нулю, прибавляется результат этого выражения для N=1. Потом - для N=2. И так до тех пор пока модуль очередного члена не станет на порядок меньше 1e-6.

В современном С++ есть шаблон "свертка" (std::reduce или std::accumulate, не помню), которой можно передать множество, бинарную операцию на этом множестве, и нейтральный элемент для этой бинарной операции. Но если ты сделаешь через свертку, то препод спросит у кого ты это списал.

Re: Рассчитать значение функции с использованием циклов while или do while

Добавлено: 02 ноя 2017, 02:22
Romeo
По первой части всё верно, а вот по reduce и accumulate сделаю замечание. Они тут не подходят, так как требуют заранее вычисленных всех значений последовательности. А это условие недостижимо из-за бесконечности ряда.

Re: Рассчитать значение функции с использованием циклов while или do while

Добавлено: 02 ноя 2017, 02:36
Absurd
Romeo писал(а):По первой части всё верно, а вот но по reduce и accumulate сделаю замечание. Они тут не подходят, так как требуют заранее вычисленных всех значений последовательности. А это условие недостижимо из-за бесконечности ряда.

Да, я вспомнил. В бусте был такой accumulate, которому указывалось до какого разряда сумма должна сойтись. в std:: такого нет.

Re: Рассчитать значение функции с использованием циклов while или do while

Добавлено: 02 ноя 2017, 02:43
alexboliam
Absurd писал(а):Ну очевидно что нужно накапливать результат в какой-то переменной-аккумуляторе. Если накапливается результат умножения, начальное значение аккумулятора должно быть 1.0. Для суммы начальный элемент - 0.0. Сначала к аккумулятору, который вначале равен нулю, прибавляется результат этого выражения для N=1. Потом - для N=2. И так до тех пор пока модуль очередного члена не станет на порядок меньше 1e-6.

В современном С++ есть шаблон "свертка" (std::reduce или std::accumulate, не помню), которой можно передать множество, бинарную операцию на этом множестве, и нейтральный элемент для этой бинарной операции. Но если ты сделаешь через свертку, то препод спросит у кого ты это списал.

Наверное, это бред, но мне пришло в голову только это :

Код: Выделить всё

int main()
{
    int n = 0;
   float ln = 0;
   float next = ((n%2)*2 - 1)*((pow((a-1),2))/n)
 while(next>0.000001 || next<-0.000001)
    {
     n++;
     ln+=next;
     printf("Current:%.6f\n,ln);
     next = ((n%2)*2 - 1)*((pow((a-1),2))/n);
      
    }
    printf("Ln:\n%.6f\n",ln);
    system("pause");
}
Подскажите, пожалуйста, что мне изменить(если не всё что написал) и добавить. Заранее спасибо!

Re: Рассчитать значение функции с использованием циклов while или do while

Добавлено: 02 ноя 2017, 02:59
Absurd
Ну можно и поизящней конечно, но что конкретно не устраивает? Ответ неверный? Вы пытались это отлаживать?

Кстати, на всех машинах начиная от Pentium-1 стоит математический сопроцессор, который на внутреннем уровне оперирует только 80-битными величинами. Так что между 32-битовым float и 64-битовым double разницы никакой нет, кроме того что double в два раз точнее. Мне, честно говоря, непонятно на чем вы пытаетесь сэкономить.

Ну и то что у вас это выражение в двух экземплярах это конечно не комильфо. Сейчас оно работает, а потом вы поменяете одно и забудете поменять другое. Или ваш подчиненный забудет. Если вам нужно поверять условие не в начале, а в конце цикла, используйте do { } while().

Кроме того, условие в цикле выглядит подозрительно. В моих программах постоянно какие-то глюки в условии "или", поэтому я стараюсь писать без них. Почему не abs(next)>0.000001 ?

И да, у тебя второй аргумент у функции pow не изменяется и равен двум.

Re: Рассчитать значение функции с использованием циклов while или do while

Добавлено: 02 ноя 2017, 10:21
Слива
float next = ((n%2)*2 - 1)*((pow((a-1),2))/n) - 1 ошибку уже нашел. :D pow(.., 2) - не во 2 степени, а в n степени.
И если в условии пишете сравнение, то его надо писать так:
#inclue <math.h>
while(fabs(next) > 1E-6)
Почему n от 0 начинается? Из ряда четко видно, что n = 1 - инициальное значение.
Можно и попроще знак рассчитать. Заводите переменную
unsigned char Sign = 1;
и потом в цикле после расчета члена ряда пишете:
Sign = -Sign;
и все. А сам член ряда будет такой:
next = Sign*((pow((a-1),n))/n);

Re: Рассчитать значение функции с использованием циклов while или do while

Добавлено: 02 ноя 2017, 11:39
Absurd
Слива писал(а):Можно и попроще знак рассчитать. Заводите переменную
unsigned char Sign = 1;
и потом в цикле после расчета члена ряда пишете:
Sign = -Sign;
Значение этого знака нужно выводить напрямую из счетчика цикла, поскольку это зависимое значение. Если в коде много левых переменных которые взаимодействуют между собой непонятным образом, то это приводит к тому что рано или поздно кто-то вносит правку где изменяется логика относительно одной переменной, но при этом не трогается поведение другой переменной. И хорошо если проблему удается найти сразу. Иногда ее приходится искать бинарным поиском, перебирая все изменения за несколько недель.