/*
Виталий Новичков
Студент МГТУ ГА, ЭВМ-1-2 2010

Программирование на языке высокого уровня
Лабораторная работа #5

9 Марта 2011 года
*/
#include <math.h>
#include <conio.h>
#include <stdio.h>
#include <iostream.h>
#include <iomanip.h>
#include <fstream.h>
#include <stdlib.h>
//Обьявление выходного файлового потока
ofstream fout;


//----Вычичление факториала----
long fact(int n)
	{
	if (n < 0) return 0;
	else if (n==0) return 1;
	else return (n * fact(n-1));
	}

//--------Вычисление X^n-------
double powx(double x, int n)
	{
	if (n==0)
	  return (1); // Здесь рекурсия прерывается
	if (x==0)
	  return (0);
	if (n==1)
	  return (x);
	if (n > 0)
	  return (x * powx(x, n-1));
	if (n < 0)
	  return (powx(x, n+1)/x);
	else
	return 1;
	}

//------Вычисление (-1)^n------
int pow1(int n)
	{
	if ((n==0)||(n%2==0))
	  return (1);
	else
	  return (-1);
	}

//Функция вычисления очередного члена ряда
float next(float x, int n)
	{
	return (pow1(n+1) * ((powx(3, ((2*n)+1)) - 3)/(fact((2*n)+1)))*powx(x, (2*n+1)));
	}

//Описание типа - указатель на функции
typedef float (*func)(float, int);


//Вычисление суммы с помощью while и рекуррентной формулы
float s1(float x, float e)
	{
	int n=3, z=0;
	float a=pow1(z)*(((pow(3,n)-3)/fact(n))*powx(x,n)), s=0;
	while (fabs(a) > e)
	  {
	  s+=a;
	  n+=2;
	  z++;
	  a=pow1(z)*(((pow(3,n)-3)/fact(n))*powx(x,n));
	  }
	return (s+a)/4;
	}

//Вычисление суммы с помощью do while и рекуррентной формулы
float s2(float x, float e)
	{
	  int n=3, z=0;
	  float a=0, s=0;
	  do
	  {
	  s+=a; a=pow1(z)*(((pow(3,n)-3)/fact(n))*powx(x,n));
	  n+=2;
	  z++;
	  }
	  while(fabs(a)>e);
	  return (s+a)/4;
	}

//Вычисление суммы с помощью While и параметра - функции
float s3(int n, float x, float e, func fn)
	{
	float f=fn(x,n), s=0;
	while(fabs(f)>e)
	  {
	  s+=f; n++; f=fn(x,n);
	  }
	return (s+f)/4;
	}

/*
  Вычисление суммы с помощью рекурсивного суммирования
  и парметра - функции
*/
float s4(int n, float x, float e, func fn)
{
	float f=fn(x, n), s=0;
	do
	{
	s+=f; n++; f=fn(x,n);
	}
	while(fabs(f)>e);
	return ((s+f)/4);
}

//Вычисление суммы с помощью рекурсивного суммирования
float s5(int n, float x, float e, func fn, int z=0)
{
	float f=fn(x,n);
	if(fabs(f)<e)
		return (f);
	else
	{
	if (z==0)
		return (f+s5(n+1, x, e, fn, z+1))/4;
	else
		return (f+s5(n+1, x, e, fn, z+1));
	}
}

void main()
{
clrscr();
/////////////////////////////////////////////////////////
float e=1.e-5; //точночть вычислений;
fout.open("n.txt"); //открытие файла результатов для записи
if (!fout)
{
cout << "Ошибка открытия файла результатов для записи"; exit(1);
}
//Вывод заголовка и шапки таблицы

fout << "\t\t\tРезультаты для e = "<<e<<'\n'
<<"╔═════════╤════════════╤════════════╤════════════╤════════════╤════════════╤═════════════╗"<<'\n'
<<"║    x    │    sin     │     s1     │     s2     │     s3     │     s4     │     s5      ║"<<'\n'
<<"╠═════════╪════════════╪════════════╪════════════╪════════════╪════════════╪═════════════╣";
//Вывод значений
for(float x=-0.4; x<=0.4; x+=0.1)
{
if ((x < 0.1)&&(x!=0)&&(x>-0.1)) x=(int)0;
fout<<endl<<'║'<<setw(8)<<setprecision(1)<<x<<setprecision(6)<<setw(2)<<'│'<<setw(12)<<pow(sin(x), 3)<<'│'
<<setw(12)<<s1(x,e)<<'│'<<setw(12)<<s2(x,e)<<'│'
<<setw(12)<<s3(1,x,e,next)<<'│'<<setw(12)<<s4(1,x,e,next)<<'│'
<<setw(13)<<s5(1,x,e,next)<<'║';
}
fout<<'\n'<<"╚═════════╧════════════╧════════════╧════════════╧════════════╧════════════╧═════════════╝";
fout.close();
/////////////////////////////////////////////////////////
printf("\nSuccess!\n\n");
getch();
}