//---------------------------------------------------------------------------
#pragma hdrstop
#include <math.h>
#include <iostream>
#include <windows.h>
#include <iomanip.h>
#pragma argsused
using namespace std;
//---------------------------------------------------------------------------
// Прототип нелинейное уравнение
double f(double);
// Прототип нахождение корня нелин. ур-я
bool Equat(double,double,double,int,double&,double&);
// Прототип табулирование функции
void Tab(double,double,double,double,double,double,int,double**,double**,double*,double*);
// Прототип вывод результатов
void RezOut(double,double,double*,double*,double**,double**,int,int);
//---------------------------------------------------------------------------
int main(int argc, char* argv[]){
   SetConsoleCP(1251);SetConsoleOutputCP(1251); // Русский язык в консоли
   double xn,dx,an,ak,da,c,d,eps,b,zt;
   int n,km,m;
   cout << "Введите xn,dx,an,ak,da,c,d,eps,n,km: " << endl;
   scanf("%lf %lf %lf %lf %lf %lf %lf %lf %i %i", &xn,&dx,&an,&ak,&da,&c,&d,&eps,&n,&km);
   // -2 0.25 1 4 1 0 8 0.00001 20 50
   system("cls");
   printf("\t\tВХОДНЫЕ ДАННЫЕ\nXn=%.2lf Dx=%.2lf An=%.2lf Ak=%.2lf Da=%.2lf C=%.2lf D=%.2lf Eps=%lf N=%i Km=%i\n\n\n",xn,dx,an,ak,da,c,d,eps,n,km);
   m=(int)((ak-an)/da+1);
   double*Mx=new double[n];
   double*Ma=new double[m];
   double **My= new double* [m];
   for(int i=0;i<m;i++) My[i]=new double[n];
   double **Er= new double* [m];
   for(int i=0;i<m;i++) Er[i]=new double[n];
   if (eps >= 1 || eps <= 0) cout << "\n\a\t\tПогрешность должна быть < 1 и > 0!\n";
   else{
      if (Equat(c,d,eps,km,b,zt)){
         Tab(an,ak,da,xn,dx,b,n,My,Er,Mx,Ma);
         RezOut(b,zt,Mx,Ma,My,Er,m,n);
      } else cout << "\n\a\t\tРешение не найдено за "<<km<<" итераций\n";
   }
   delete [] Mx;
   delete [] Ma;
   for(int i=0;i<m;i++) delete[]My[i];
   delete [] My;
   for(int i=0;i<m;i++) delete[]Er[i];
   delete [] Er;
   system("pause");return 0;
}
//---------------------------------------------------------------------------
// Нелинейное уравнение
double f(double x){
  return (exp(-x)+x*x-2);
}
//---------------------------------------------------------------------------
// Нахождение корня нелинейного уравнения методом деления отрезка пополам
bool Equat(double c,double d,double eps,int km,double&b,double&zt){
   int i=1;
   double z;
   while(i<=km){
      z=(c+d)/2;
      if(fabs(f(z)) > eps)
         if(f(c)*f(z) > 0) c=z; else d=z;
      else{
         i=km;
         b=z;
         zt=f(z); // Погрешность вычисления корня по невязке
         return true;
      }
      i++;
   }
   return false;
}
//---------------------------------------------------------------------------
// Табулирование функции
void Tab(double an,double ak,double da,double xn,double dx,double b,int n,double**My,double**Er,double*Mx,double*Ma){
   double a=an,x;
   int i=0;
   while (a<=ak){
      x=xn;
      for (int j=0;j<n;j++){
         Mx[j]=x;
         if (x<1){
            My[i][j]=4*b-exp(a*x);
            Er[i][j]=0;
         }   
         else
            if (a*x+b*b>0){
               My[i][j]=(x*x*x)/(sqrt(a*x+b*b));
               Er[i][j]=0;
            }
            else Er[i][j]=1;
         x+=dx;
      }
      Ma[i]= a;
      i++;
      a+=da;
   }
}
//---------------------------------------------------------------------------
// Вывод результатов
void RezOut(double b,double zt,double*Mx,double*Ma,double**My,double**Er,int m,int n){
   cout << "\t\tРЕЗУЛЬТАТЫ ВЫЧИСЛЕНИЯ\nКорень уранения: " << b << "; Невязка: " << zt << endl;
   cout<<"\nТаблица значений функции:\n"<<endl;
   printf("%-15s", "X/A");
   for(int i=0;i<m;i++) printf("%2s%i%2s%-10.3lf","A[",i,"]=",Ma[i]);
   cout << endl;
   for(int i=0;i<n;i++){
      printf("%2s%02i%2s%-9.2lf","X[",i,"]=",Mx[i]);
      for (int j=0;j<m;j++){
         if(Er[j][i]==1)
            printf("%-15s", "Err");
         else
            printf("%-15.6lf", My[j][i]);
      }
      cout << endl;
   }
}
//---------------------------------------------------------------------------
