Здраствуйте, сейчас прохожу тему с итерационными циклами, надо написать программу, которая "рассчитает с точностью до 6 цифр значение функции Lnx. Сравнить полученное с помощью ряда значение со значением , полученным стандартной функцией."
Вопросы таковы: как задать рассчет до n-ой цифры?(вроде что-то через %, но не уверен)
Как написать именно эту функцию? Чтобы перед непарным членом стоял знак "+", а перед парным "-".
И последнее, через какой цикл все оформить?
Спасибо за внимание!
Рассчитать значение функции с использованием циклов while или do while
Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain
-
- Сообщения: 5
- Зарегистрирован: 16 окт 2017, 01:05
У вас нет необходимых прав для просмотра вложений в этом сообщении.
-
- Сообщения: 1213
- Зарегистрирован: 26 фев 2004, 13:24
- Откуда: Pietari, Venäjä
- Контактная информация:
Это сходящаяся последовательность. Каждый член меньше предыдущего не в разы, а на порядок. Это значит что когда N-ный член на порядок меньше 1e-6, то сумма всего остального от N до +Inf на шестой разряд повлиять заведомо уже не сможет, иначе ряд не был бы сходящимся.alexboliam писал(а):Здраствуйте, сейчас прохожу тему с итерационными циклами, надо написать программу, которая "рассчитает с точностью до 6 цифр значение функции Lnx. Сравнить полученное с помощью ряда значение со значением , полученным стандартной функцией."
(N%2)*2 - 1 Даст -1 для четных N, и 1 для нечетных (остаток от деления на два даст 1 для нечетных, и 0 для четных. Это уможается на два чтобы 1 отобразить на 2 а ноль - на ноль. Потом вычитаем единичку чтобы получить -1 для четных и 1 - для нечетных). Если член умножить на эту величину, то он будет либо положительным, либо отрицательным. Модуль от умножения на единичку не изменится.alexboliam писал(а): Как написать именно эту функцию? Чтобы перед непарным членом стоял знак "+", а перед парным "-".
Да без разницы, все циклы эквивалентны. Можно написать программу любой сложности пользуясь только for. Или только while. Разница только в удобстве и наглядности для каждого конкретного слячая.alexboliam писал(а): И последнее, через какой цикл все оформить?
2B OR NOT(2B) = FF
-
- Сообщения: 5
- Зарегистрирован: 16 окт 2017, 01:05
Absurd писал(а):Это сходящаяся последовательность. Каждый член меньше предыдущего не в разы, а на порядок. Это значит что когда N-ный член на порядок меньше 1e-6, то сумма всего остального от N до +Inf на шестой разряд повлиять заведомо уже не сможет, иначе ряд не был бы сходящимся.
(N%2)*2 - 1 Даст -1 для четных N, и 1 для нечетных (остаток от деления на два даст 1 для нечетных, и 0 для четных. Это уможается на два чтобы 1 отобразить на 2 а ноль - на ноль. Потом вычитаем единичку чтобы получить -1 для четных и 1 - для нечетных). Если член умножить на эту величину, то он будет либо положительным, либо отрицательным. Модуль от умножения на единичку не изменится.
Да без разницы, все циклы эквивалентны. Можно написать программу любой сложности пользуясь только for. Или только while. Разница только в удобстве и наглядности для каждого конкретного слячая.
Спасибо за ответ! Я сначала думал, что последовательность задается как сумма (см. вложение). Но все же не могу понять, как это записать на C++.
У вас нет необходимых прав для просмотра вложений в этом сообщении.
-
- Сообщения: 1213
- Зарегистрирован: 26 фев 2004, 13:24
- Откуда: Pietari, Venäjä
- Контактная информация:
alexboliam писал(а):Спасибо за ответ! Я сначала думал, что последовательность задается как сумма (см. вложение). Но все же не могу понять, как это записать на C++.
Ну очевидно что нужно накапливать результат в какой-то переменной-аккумуляторе. Если накапливается результат умножения, начальное значение аккумулятора должно быть 1.0. Для суммы начальный элемент - 0.0. Сначала к аккумулятору, который вначале равен нулю, прибавляется результат этого выражения для N=1. Потом - для N=2. И так до тех пор пока модуль очередного члена не станет на порядок меньше 1e-6.
В современном С++ есть шаблон "свертка" (std::reduce или std::accumulate, не помню), которой можно передать множество, бинарную операцию на этом множестве, и нейтральный элемент для этой бинарной операции. Но если ты сделаешь через свертку, то препод спросит у кого ты это списал.
2B OR NOT(2B) = FF
- Romeo
- Сообщения: 3091
- Зарегистрирован: 02 мар 2004, 17:25
- Откуда: Крым, Севастополь
- Контактная информация:
По первой части всё верно, а вот по reduce и accumulate сделаю замечание. Они тут не подходят, так как требуют заранее вычисленных всех значений последовательности. А это условие недостижимо из-за бесконечности ряда.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
-
- Сообщения: 1213
- Зарегистрирован: 26 фев 2004, 13:24
- Откуда: Pietari, Venäjä
- Контактная информация:
Romeo писал(а):По первой части всё верно, а вот но по reduce и accumulate сделаю замечание. Они тут не подходят, так как требуют заранее вычисленных всех значений последовательности. А это условие недостижимо из-за бесконечности ряда.
Да, я вспомнил. В бусте был такой accumulate, которому указывалось до какого разряда сумма должна сойтись. в std:: такого нет.
2B OR NOT(2B) = FF
-
- Сообщения: 5
- Зарегистрирован: 16 окт 2017, 01:05
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");
}
-
- Сообщения: 1213
- Зарегистрирован: 26 фев 2004, 13:24
- Откуда: Pietari, Venäjä
- Контактная информация:
Ну можно и поизящней конечно, но что конкретно не устраивает? Ответ неверный? Вы пытались это отлаживать?
Кстати, на всех машинах начиная от Pentium-1 стоит математический сопроцессор, который на внутреннем уровне оперирует только 80-битными величинами. Так что между 32-битовым float и 64-битовым double разницы никакой нет, кроме того что double в два раз точнее. Мне, честно говоря, непонятно на чем вы пытаетесь сэкономить.
Ну и то что у вас это выражение в двух экземплярах это конечно не комильфо. Сейчас оно работает, а потом вы поменяете одно и забудете поменять другое. Или ваш подчиненный забудет. Если вам нужно поверять условие не в начале, а в конце цикла, используйте do { } while().
Кроме того, условие в цикле выглядит подозрительно. В моих программах постоянно какие-то глюки в условии "или", поэтому я стараюсь писать без них. Почему не abs(next)>0.000001 ?
И да, у тебя второй аргумент у функции pow не изменяется и равен двум.
Кстати, на всех машинах начиная от Pentium-1 стоит математический сопроцессор, который на внутреннем уровне оперирует только 80-битными величинами. Так что между 32-битовым float и 64-битовым double разницы никакой нет, кроме того что double в два раз точнее. Мне, честно говоря, непонятно на чем вы пытаетесь сэкономить.
Ну и то что у вас это выражение в двух экземплярах это конечно не комильфо. Сейчас оно работает, а потом вы поменяете одно и забудете поменять другое. Или ваш подчиненный забудет. Если вам нужно поверять условие не в начале, а в конце цикла, используйте do { } while().
Кроме того, условие в цикле выглядит подозрительно. В моих программах постоянно какие-то глюки в условии "или", поэтому я стараюсь писать без них. Почему не abs(next)>0.000001 ?
И да, у тебя второй аргумент у функции pow не изменяется и равен двум.
2B OR NOT(2B) = FF
float next = ((n%2)*2 - 1)*((pow((a-1),2))/n) - 1 ошибку уже нашел. 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);
И если в условии пишете сравнение, то его надо писать так:
#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);
-
- Сообщения: 1213
- Зарегистрирован: 26 фев 2004, 13:24
- Откуда: Pietari, Venäjä
- Контактная информация:
Значение этого знака нужно выводить напрямую из счетчика цикла, поскольку это зависимое значение. Если в коде много левых переменных которые взаимодействуют между собой непонятным образом, то это приводит к тому что рано или поздно кто-то вносит правку где изменяется логика относительно одной переменной, но при этом не трогается поведение другой переменной. И хорошо если проблему удается найти сразу. Иногда ее приходится искать бинарным поиском, перебирая все изменения за несколько недель.Слива писал(а):Можно и попроще знак рассчитать. Заводите переменную
unsigned char Sign = 1;
и потом в цикле после расчета члена ряда пишете:
Sign = -Sign;
2B OR NOT(2B) = FF