Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > Поправьте/допишите код!


Автор: Tep4k111 3.12.2013, 11:16
Собственно вот условие задачи:
Составить программу  и вычислить  сумму ряда с точностью  e=pow(10,-3), e=pow(10,-6), e=pow(10,-9).  Сравнить число итераций для каждого из этих  случаев.  

user posted image

Вот мой код: 
Код
#include <iostream.h>
#include <conio.h>
#include <math.h>
#include <stdio.h>
void main ()
{
float k=0,n,S1,x,S,p,f=1;
printf("Enter x= ");
scanf("%f", &x);
S=0.0;
n=1;   //nachal`noe dlya vichisleniya ryada chlena
while (S>e)
{
for (k=0; k<=n; k++)
S+=pow(1.0,k)*(-1.0)*sin(2.0*k+1.0)*x/2.0*k+1.0; //сама фу-я
n++;
}
cout<<"S="<<S<<endl;
f=1;
while (S>=0)
{
f*=-x*x*(2*k+1)/(2*k*k+5*k+1); // формула Dalamber для вычисления итераций
if (f>e) cout<<"The end"<<endl;
else S+=f;
k++;
}
cout<<"S="<<S<<endl;
cout<<"chislo iteraciy ="<<k;
p=3.14;
if ((x>0.0)&&(x<p/2.0))
S1=0.5*log(tan(x/2.0+p/4.0));
cout<<S1<<endl;
if (S=S1) cout<<"true"<<endl; //сравнение
else cout<<"banan";
getch();
clrscr();
}


Модератор: не забываем пользоваться кнопочкой "Код"

Автор: smalcom 3.12.2013, 12:53
1. используйте тег "код". мусорник же
2. в чём проблема?

Автор: feodorv 3.12.2013, 15:46
Цитата(Tep4k111 @  3.12.2013,  12:16 Найти цитируемый пост)
if (S=S1) cout<<"true"<<endl; //сравнение
else cout<<"banan";

Числа с плавающей точкой так сравнивать не стоит. У Вас заранее задана точность вычисления, поэтому сравнение должно выглядеть так:
Код

if( fabs( S - S1 ) <= epsilon ) ...

хотя, конечно, не понятно, какая точность задана - относительная или абсолютная...


Цитата(Tep4k111 @  3.12.2013,  12:16 Найти цитируемый пост)
n=1;   //nachal`noe dlya vichisleniya ryada chlena
Цитата(Tep4k111 @  3.12.2013,  12:16 Найти цитируемый пост)
for (k=0; k<=n; k++)
Ну и всегда имеете 2 итерации, при которых всё в S складывается и складывается...


Цитата(Tep4k111 @  3.12.2013,  12:16 Найти цитируемый пост)
S+=pow(1.0,k)*(-1.0)*sin(2.0*k+1.0)*x/2.0*k+1.0; //сама фу-я

Смысла возводить 1.0 в степень k никакого нет (а потом умножать на -1), тем более в формуле стоит -1 в степени k (то есть это знакопеременный ряд). 
/2.0*k+1.0 компилятором воспринимается несколько иначе, чем Вам хотелось бы, выражение нужно взять в скобки: (2.0*k+1.0)


При чём здесь Даламбер, наверное, не скажет никто, судя по всему, это из какого-то другого задания.


Цитата(Tep4k111 @  3.12.2013,  12:16 Найти цитируемый пост)
while (S>e)

e не только не задана, но даже не прописана в числе переменных.


Никакого сравнения числа итераций нет...


Цитата(Tep4k111 @  3.12.2013,  12:16 Найти цитируемый пост)
float k=0,n

Зачем счётчику цикла быть float???

Автор: borisbn 3.12.2013, 16:34
Цитата(feodorv @  3.12.2013,  15:46 Найти цитируемый пост)
if (S=S1) cout<<"true"<<endl; //сравнение

Это даже не сравнение ))

Tep4k111, пока не отформатируешь по-человечески код, тебе вряд-ли кто-то захочет помогать.

feodorv, пожалуй, исключение, подтверждающее правило  smile 

Автор: Tep4k111 3.12.2013, 16:45
Цитата(feodorv @ 3.12.2013,  15:46)
Цитата(Tep4k111 @  3.12.2013,  12:16 Найти цитируемый пост)
if (S=S1) cout<<"true"<<endl; //сравнение
else cout<<"banan";

Числа с плавающей точкой так сравнивать не стоит. У Вас заранее задана точность вычисления, поэтому сравнение должно выглядеть так:
Код

if( fabs( S - S1 ) <= epsilon ) ...

хотя, конечно, не понятно, какая точность задана - относительная или абсолютная...


Цитата(Tep4k111 @  3.12.2013,  12:16 Найти цитируемый пост)
n=1;   //nachal`noe dlya vichisleniya ryada chlena
Цитата(Tep4k111 @  3.12.2013,  12:16 Найти цитируемый пост)
for (k=0; k<=n; k++)
Ну и всегда имеете 2 итерации, при которых всё в S складывается и складывается...


Цитата(Tep4k111 @  3.12.2013,  12:16 Найти цитируемый пост)
S+=pow(1.0,k)*(-1.0)*sin(2.0*k+1.0)*x/2.0*k+1.0; //сама фу-я

Смысла возводить 1.0 в степень k никакого нет (а потом умножать на -1), тем более в формуле стоит -1 в степени k (то есть это знакопеременный ряд). 
/2.0*k+1.0 компилятором воспринимается несколько иначе, чем Вам хотелось бы, выражение нужно взять в скобки: (2.0*k+1.0)


При чём здесь Даламбер, наверное, не скажет никто, судя по всему, это из какого-то другого задания.


Цитата(Tep4k111 @  3.12.2013,  12:16 Найти цитируемый пост)
while (S>e)

e не только не задана, но даже не прописана в числе переменных.


Никакого сравнения числа итераций нет...


Цитата(Tep4k111 @  3.12.2013,  12:16 Найти цитируемый пост)
float k=0,n

Зачем счётчику цикла быть float???

спасибо за ценный комментарий, но меня всё так интересует, можно ли как-то показать эти итерации? Насчёт float: там целочисленные значения должны быть, мой косяк. Как я понял, Даламбер там вообще не нужен. Переменная "e" была задана через double. Нужно ли так делать, либо лучше вводить? Тогда как ввести степень?  

Автор: baldina 3.12.2013, 17:26
1. надо оформить функцию в виде функции, так удобнее. заодно исправить её, т.к. у вас функция не соответствует картинке

Код

double Series (int k, double x) {
 double arg = 2.0*k+1.0;
 if (k%2) // нечетная степень -1
   x = -x;
 return sin(arg)*x/arg;
}


функцию для расчета точного значения - тоже. и pi при этом взять поточнее, например как результат arccos(-1)
Код

const double pi=acos(-1.0);
double f (double x) {
  return 0.5*log(tan(x/2.0+pi/4.0));
}


2. у вас задание посчитать сумму несколько раз, с заданной точностью, и выяснить число итераций
напрашивается решение - расчет суммы оформить в виде функции. разумно также задать максимальное число итераций, что бы программа всегда завершалась.
Если число итераций совпало с максимальным значением, значит требуемая точность не достигнута.
Код

void sum (
  ,double x 
  ,double y // точное значение 
  ,double epsilon // желаемая точность
) 
{
   double S=0;
   int k;
   int m = ... ; // максимальное число итераций
   for (k=0; k < m; ++k) { 
      S += Series (...);
      if (fabs(S-y) < epsilon) {
          // достигли заданной точности
          break;
      }
   }
   if (k == m)
     cout << "Расчет прерван по числу итераций\n".
   cout << k << ' ' << S << ' ' << y << ' ' << epsilon << endl;
}


3. Вот эту функцию и надо вызывать для различных значений epsilon.
Код

double y = f(x);
sum (x, y, 1e-3); 
sum (x, y, 1e-6); 
sum (x, y, 1e-9); 


4. Если введенное значение x не лежит в диапазоне ]0..pi/2[, то и ряд считать смысла нет, надо попросить пользователя вернуть правильное значение

Автор: Tep4k111 4.12.2013, 01:12
Цитата(baldina @ 3.12.2013,  17:26)
1. надо оформить функцию в виде функции, так удобнее. заодно исправить её, т.к. у вас функция не соответствует картинке

Код

double Series (int k, double x) {
 double arg = 2.0*k+1.0;
 if (k%2) // нечетная степень -1
   x = -x;
 return sin(arg)*x/arg;
}


функцию для расчета точного значения - тоже. и pi при этом взять поточнее, например как результат arccos(-1)
Код

const double pi=acos(-1.0);
double f (double x) {
  return 0.5*log(tan(x/2.0+pi/4.0));
}


2. у вас задание посчитать сумму несколько раз, с заданной точностью, и выяснить число итераций
напрашивается решение - расчет суммы оформить в виде функции. разумно также задать максимальное число итераций, что бы программа всегда завершалась.
Если число итераций совпало с максимальным значением, значит требуемая точность не достигнута.
Код

void sum (
  ,double x 
  ,double y // точное значение 
  ,double epsilon // желаемая точность
) 
{
   double S=0;
   int k;
   int m = ... ; // максимальное число итераций
   for (k=0; k < m; ++k) { 
      S += Series (...);
      if (fabs(S-y) < epsilon) {
          // достигли заданной точности
          break;
      }
   }
   if (k == m)
     cout << "Расчет прерван по числу итераций\n".
   cout << k << ' ' << S << ' ' << y << ' ' << epsilon << endl;
}


3. Вот эту функцию и надо вызывать для различных значений epsilon.
Код

double y = f(x);
sum (x, y, 1e-3); 
sum (x, y, 1e-6); 
sum (x, y, 1e-9); 


4. Если введенное значение x не лежит в диапазоне ]0..pi/2[, то и ряд считать смысла нет, надо попросить пользователя вернуть правильное значение

спасибо!

Автор: Tep4k111 6.12.2013, 22:49
Цитата(Tep4k111 @ 4.12.2013,  01:12)
Цитата(baldina @ 3.12.2013,  17:26)
1. надо оформить функцию в виде функции, так удобнее. заодно исправить её, т.к. у вас функция не соответствует картинке

Код

double Series (int k, double x) {
 double arg = 2.0*k+1.0;
 if (k%2) // нечетная степень -1
   x = -x;
 return sin(arg)*x/arg;
}


функцию для расчета точного значения - тоже. и pi при этом взять поточнее, например как результат arccos(-1)
Код

const double pi=acos(-1.0);
double f (double x) {
  return 0.5*log(tan(x/2.0+pi/4.0));
}


2. у вас задание посчитать сумму несколько раз, с заданной точностью, и выяснить число итераций
напрашивается решение - расчет суммы оформить в виде функции. разумно также задать максимальное число итераций, что бы программа всегда завершалась.
Если число итераций совпало с максимальным значением, значит требуемая точность не достигнута.
Код

void sum (
  ,double x 
  ,double y // точное значение 
  ,double epsilon // желаемая точность
) 
{
   double S=0;
   int k;
   int m = ... ; // максимальное число итераций
   for (k=0; k < m; ++k) { 
      S += Series (...);
      if (fabs(S-y) < epsilon) {
          // достигли заданной точности
          break;
      }
   }
   if (k == m)
     cout << "Расчет прерван по числу итераций\n".
   cout << k << ' ' << S << ' ' << y << ' ' << epsilon << endl;
}


3. Вот эту функцию и надо вызывать для различных значений epsilon.
Код

double y = f(x);
sum (x, y, 1e-3); 
sum (x, y, 1e-6); 
sum (x, y, 1e-9); 


4. Если введенное значение x не лежит в диапазоне ]0..pi/2[, то и ряд считать смысла нет, надо попросить пользователя вернуть правильное значение

спасибо!

Вот что получилось... укажите на недочёты.


Код

#include <iostream.h>
#include <conio.h>
#include <math.h>
#include <stdio.h>
void main ()
{
int x;
cout<<"Enter the number x =";
cin>>x;
int iter=0;
 int iter2=0;
int iter3=0;  
 double S=0.0, arg, F;
double S2=0.0;
 double S3=0.0;
double pi=3.14;
 double e=pow(10,-3);
double e2=pow(10,-6);
 double e3=pow(10,-9);
double F4=0.5*log(tan(x/2.0+pi/4.0));

      for (int k=0; fabs(S-F4)>e; k++)
     {
      arg=2.0*k+1.0;
      double F=pow(-1.0,k)*sin(arg)*x/arg;
      S+=F;
      iter+=1;
     }

cout<<"\niter ="<<iter<<"\nS ="<<S<<"\nF2="<<F4;

     for (int k2=0; fabs(S2-F4)>e2; k2++)
    {
     arg=2.0*k2+1.0;
     double F2=pow(-1.0,k2)*sin(arg)*x/arg;
     S2+=F2;
     iter2+=1;
    }

cout<<"\niter2 ="<<iter2<<"\nS2 ="<<S2<<"\nF2="<<F4;

    for (int k3=0; fabs(S3-F4)>e3; k3++)
       {
    arg=2.0*k3+1.0;
    double F3=pow(-1.0,k3)*sin(arg)*x/arg;
    S3+=F3;
    iter3+=1;
       }

cout<<"iter3 ="<<iter3<<"\nS3 ="<<S3<<"\nF2="<<F4;
getch();
clrscr();
}




Автор: baldina 6.12.2013, 23:31
код не отформатирован, вырви глаз
контроля числа итераций нет, возможно зацикливание (ряд кстати сходится медленно)
бессмысленно считаете с точностью 1e-9, задавая pi с точностью 1e-2
зачем числа 1e-3, 1e-6, 1e-9 вычислять при помощи pow()?
переменные iter1..3 лишние, у вас есть k 
контроль значения х отсутствует
  
про copy-paste я уж не говорю, видимо функции С++ вы ниасилили

Добавлено через 59 секунд
ну вобщем на троечку, если у преподавателя настроение хорошее  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)