Распечатка текста программы
main.cpp – главный элемент проекта
#include <cstdlib>
#include <iostream>
#include <graphics.h>
#include <conio.h>
# include <stdio.h>
# include <math.h>
#include <fstream>
#include "func.h"
#include "graph.h"
#include "root.h"
using namespace std;
float getFloatValue(char *label)
{//получить от пользователя числовое значение
float value;
while(1)
{
fflush(stdin);//очистка буфера
cout<<label;
if((scanf("%f",&value))==0)//если введено не число
cout<<"Tol'ko chislovoe znachenie!\n";
else break;//иначе выход из цикла
}
return value;//возращаем введеное число
}
int main()
{
float a, b, c,//коэффициенты уравнения
x0,//начальное значение
e;//погрешность
int successVubor,//успешный выбор команды меню и корректный выбор исходных значений
k;//номер уравнения
cout<<"\nVvedite nomer reshaemogo yravneniya (1-3).\n";
cin >> k;
k--;
do
{
cout<<"\nVvod dannuh:\n 1. S klaviatyru;\n 2. Iz faila;\n e. Vuhod.\n";
successVubor = 0;
char command;
cin >> command;
switch(command)
{
case '1'://ввод исходных данных с клавиатуры
x0 = getFloatValue("\nVvedite nachal'noe znachenie x0: ");
a = getFloatValue("Vvedite znachenie a: ");
b = getFloatValue("Vvedite znachenie b: ");
c = getFloatValue("Vvedite znachenie c: ");
e = getFloatValue("Vvedite pogreshnost vushisleniya e: ");
break;
case '2'://чтение данных из файла
do
{
cout<<"\nVvedite pyt' i imya faila (vuhod iz programmu: e): ";
char fileName[40];
cin>>fileName;
if(!strcmp(fileName, "e"))
exit(1);
ifstream stream(fileName, ios::in);
if(stream == NULL)
cout<<"Oshibka otkrutiya faila. Prover'te pravilnost pyti faila.";
else
{
stream>>x0>>a>>b>>c>>e;
stream.close();
break;
}
}
while(1);
break;
/*case '3'://по умолчанию
x0 = 3;
a = 12;
b = -2;
c = -1;//коэффициенты уравнения
e = 0.001;
break;*/
case 'e'://выход
exit(1);
break;
default://любая другая клавиша = неудачный выбор подменю
successVubor = 1;
}
}
while(successVubor);//пока не будет осуществлен корректный ввод исходных данных
int nSteps;//кол-во шагов при вычислении корня
//for(int k = 0; k < 3; k++)//для каждого из 3х уравнений
//{//вычисляем приближенное значение интеграла, точное значение, абсолютную и относительную погрешности
cout<<"\n\nNahodim koren' "<<(k + 1)<<" yravneniya.";
float pribl = findX(x0, a, b, c, e, k, &nSteps),
toch = getX(x0, a, b, c, k);
cout<<"\nNaidennoe znachenie: "<<pribl<<
" (f(x) = "<<f(pribl, a, b, c, k)<<
")\nTochnoe znachenie: "<<toch<<
" (f(x) = "<<f(toch, a, b, c, k)<<
")\nAbsolytnaya pogr: "<<fabs(pribl - toch);
if(toch != 0)
cout<<"\nOtnositelnaya pogr: "<<fabs((pribl - toch)) / toch * 100;
else cout<<"\nTochnoe znachenie = 0. Otnositelny'y pogreshnost' nelzya naiti.";
//}
//cout<<endl<<nSteps[0]<<" steps "<<nSteps[1]<<" "<<nSteps[2];
cout<<"\n";
system("PAUSE");
showGraphs(x0, a, b, c, nSteps, k);//отображаем графики этих уравнений
return 0;
}
root.cpp – нахождение корней уравнения
# include <math.h>
#include "func.h"
float findX(float x0, float a, float b, float c, float e, int k, int *nSteps)
{
//float ax = x1, bx = x2;
*nSteps = 0;
float lastX;
float xn = x0;
while(fabs(f(xn, a, b, c, k)) > e && *nSteps < 1000)//lastX - xn
{
*nSteps = *nSteps + 1;
lastX = xn;
if(fProizv(lastX, a, b, c, k) != 0)
xn = lastX - f(lastX, a, b, c, k) / fProizv(lastX, a, b, c, k);
else std::cout<<"\nProizvodnaya ravna 0.";
}
if(*nSteps == 1000)
std::cout<<"\nProizvedeno 1000 iteracij, trebyemaya tochnost' ne dostignyta. Vozmojno pri zadannuh ishodnuh dannuh net kornya ili ryad ne shoditsya.";
return xn;
}
float getX(float x0, float a, float b, float c, int k)
{//нахождение точного решения
switch(k)
{
case 0://решение кубического уравнения по формуле Кардано
float al, be,//альфа, бетта
p, q,//коэффициенты канонического уравнения
de;//дискриминант (дельта)
p = b / a;
q = c / a;
de = pow(p / 3, 3) + pow(q / 2, 2);
al = pow(-q / 2 + pow(de, 0.5), (float)1/3);
if(-q / 2 - pow(de, 0.5) >= 0)
be = pow(-q / 2 - pow(de, 0.5), (float)1/3);
else
be = -pow(fabs(-q / 2 - pow(de, 0.5)), (float)1/3);
if(de <= 0)
std::cout<<"\nYravnenie imeet neskol'ko deistvitelnuh kornei.";
return al + be;
case 1:
if(a != 0)
{
if(fabs(c / a) > 1)
{
std::cout<<"\nArgyment arcsin (-c/a) ne mojet but' > 1";
return 0;
}
}
else
{
std::cout<<"\nZnamenatel (a) raven 0.";
return 0;
}
return asin(-c / a) + 2 * M_PI * (int) (x0 - asin(-c / a) + b) / (2 * M_PI) - b;
case 2:
if(a != 0)
{
if (fabs(exp(-c / a) - b - x0) < fabs(-exp(-c / a) - b - x0))
return exp(-c / a) - b;
else
return -exp(-c / a) - b;
}
else
std::cout<<"Oshibka. Kornya net (a = 0)!";
return 0;
default:
return 0;
}
}
float findXWithNumber(float x0, float a, float b, float c, int step, int k)
{//получить значение х при заданном номере итерации вычисления
float lastX;
int i = 0;
float xn = x0;
while(i != step)
{
i++;
lastX = xn;
if(fProizv(x0, a, b, c, k) != 0)
xn = lastX - f(lastX, a, b, c, k) / fProizv(lastX, a, b, c, k);
}
return xn;
}
Заголовочный файл root.h
float findX(float x0, float a, float b, float c, float e, int k, int *nSteps);
float getX(float x0, float a, float b, float c, int k);
float findXWithNumber(float x0, float a, float b, float c, int step, int k);
func.cpp – вычисление значения функции и ее производной от заданного аргумента
#include <iostream>
# include <math.h>
float f(float x, float a, float b, float c, int k)
{//значение фукнции под номером k(нумерация с нуля) при аргументе x, с заданными коэффициентами a, b, c
switch(k)
{
case 0:
return a * pow(x, 3) + b * x + c;
case 1:
return a * sin(x + b) + c;
case 2:
{
if(x + b != 0)
return a * log (fabs(x + b)) + c;
else
{
std::cout<<"Oshibka. Znamenatel' prinimaet nylevoe znachenie!";
return 0;
}
}
default:
return 0;
}
}
float fProizv(float x, float a, float b, float c, int k)
{//производная функций
switch(k)
{
case 0:
return 3 * a * pow(x, 2) + b;
case 1:
return a * cos(x + b);
case 2:
if(x + b != 0)
{
if(x + b > 0)
return a / fabs(x + b);
else
return - a / fabs(x + b);
}
else
{
std::cout<<"Oshibka. Znamenatel' prinimaet nylevoe znachenie!";
return 0;
}
default:
return 0;
}
}
Заголовочный файл func.h
float f(float x, float a, float b, float c, int k);
float fProizv(float x, float a, float b, float c, int k);
graph.cpp – отображение графиков функций и процесс вычисления интеграла в графическом режиме
#include <graphics.h>
#include "root.h"
#include "func.h"
#include <iostream>
int gdriver = DETECT, gmode, errorcode;
void showGraph(float x0, float a, float b, float c, int nSteps, int k,
int miny, int maxy)
{//отображение графика одного уравнения с номером k на области от minx до miny по вертикали
int n = 30;
float x1 = findXWithNumber(x0, a, b, c, 0, k),
x2 = findXWithNumber(x0, a, b, c, 0, k);
for(int i = 1; i <= nSteps; i++)
{
float x = findXWithNumber(x0, a, b, c, i, k);
if(x1 > x)
x1 = x;
if(x2 < x)
x2 = x;
}
float h = (x2 - x1) / n;//ширина шага
int minx = 80,// и miny, maxy - границы области в которой нужно нарисовать график
maxx = 850;
float y1 = f(x1, a, b, c, k),//мин и макс значение функции
y2 = f(x1, a, b, c, k),
dx;
for(int i = 1; i <= n; i++)
{//поиск мин и макс значений функции у1 и у2
float zn = f(x1 + i * h, a, b, c, k);
if(y1 > zn)
y1 = zn;
if(y2 < zn)
y2 = zn;
}
float kx, ky;//коэффициенты растяжения графика по 0х и по 0у на всю область
kx = (maxx - minx)/(x2 - x1);
ky = (maxy - miny)/(y2 - y1);
int Oy = (int)(ky * y2) + miny;//где находится ось (уравнение x=0)
int OyOtobr;//отображаемая ось
if (ky * y2 + miny > maxy)//если уравнение x=0 находится вне области отображения графика, отображаем ось внизу области
OyOtobr = maxy;
else//иначе на том уровне, где она должна быть
OyOtobr = (int)(ky * y2) + miny;
dx = kx * h;//шаг по 0х в пиксельном выражении
setcolor(WHITE);//оси белым
moveto(minx, OyOtobr);//прорисовка осей
lineto(maxx + 8, OyOtobr);
lineto(maxx + 3, OyOtobr - 5);
moveto(maxx + 8, OyOtobr);
lineto(maxx + 3, OyOtobr + 5);
moveto(minx, maxy + 3);
lineto(minx, miny - 8);
lineto(minx + 5, miny - 3);
moveto(minx, miny - 8);
lineto(minx - 5, miny - 3);
if(x1 * x2 < 0)//отображение точки (0,0), если она оказалась в отображаем области
outtextxy(minx + (int)(x1 * kx) - 3, OyOtobr + 5, "(0,0)");
char *s;
s = new char[5];
outtextxy(maxx, OyOtobr + 5, gcvt(x2, 4, s));//цены деления - мин и макс по осям
outtextxy(minx, OyOtobr + 5, gcvt(x1, 4, s));
outtextxy(5, maxy - 10, gcvt(y1, 4, s));
outtextxy(5, miny - 10, gcvt(y2, 4, s));
moveto(maxx, OyOtobr + 2);//штрихи для них
lineto(maxx, OyOtobr - 2);
moveto(minx - 3, miny);
lineto(minx + 3, miny);
moveto(minx - 3, maxy);
lineto(minx + 3, maxy);
setcolor(GREEN);//схема вычисления корня зеленым
if(y1 * y2 <= 0.2)//если есть корень на отображаемом отрезке (приблизительно)
{
float x = findXWithNumber(x0, a, b, c, 0, k);
moveto(minx + (int)((x - x1) * kx), Oy);
lineto(minx + (int)((x - x1) * kx), Oy - (int)(f(x, a, b, c, k) * ky));
for(int i = 1; i < nSteps; i++)
{
x = findXWithNumber(x0, a, b, c, i, k);
lineto(minx + (int)((x - x1) * kx), Oy);
lineto(minx + (int)((x - x1) * kx), Oy - (int)(f(x, a, b, c, k) * ky));
}
}
setcolor(RED);//график красным
moveto(minx, Oy - (int)(f(x1, a, b, c, k) * ky));//встаем в начало
for(int i = 0; i <= n; i++)//и прорисовываем график
lineto(minx + (int)(dx * i), Oy - (int)(f(x1 + i * h, a, b, c, k) * ky));
}
void showGraphs(float x0, float a, float b, float c, int nSteps, int k)
{
initwindow(900, 800); //открытие окна графического режима
outtextxy(10, 5, "Graphik yravneniya:");
//outtextxy(10, 260, "Vtoroe yravnenie:");
// outtextxy(10, 520, "Tretie yravnenie:");
showGraph(x0, a, b, c, nSteps, k, 30, 700);//отображение графика первого уравнения на участке экрана от 30 до 250 пикселей сверху
//showGraph(x0, a, b, c, nSteps[1], 1, 290, 510);//отображение графика второго уравнения -//-
//showGraph(x0, a, b, c, nSteps[2], 2, 560, 770);//отображение графика третьего уравнения -//-
system("PAUSE");
closegraph();//выход из графического режима
}
Заголовочный файл graph.h
void showGraph(float x0, float a, float b, float c, int nSteps, int k,
int miny, int maxy);
void showGraphs(float x0, float a, float b, float c, int nSteps, int k);
Выводы по работе
Изучен теоретический материал для решения задачи нахождения корня уравнения методом Ньютона. Разработан алгоритм решения поставленной задачи, разработана и протестирована программа на языке С, выявленные ошибки в ходе тестирования устранены, контрольное тестирование ошибок не показала. Определены точные решения для каждого из уравнений. Изучен и применен теоретический материал для работы с графикой на языке C.
Использованная литература
1. Wikipedia. Метод Ньютона. http://ru.wikipedia.org/wiki/Метод_Ньютона. Интернет ресурс. Вход свободный.
2. Решение кубических уравнений. Формула Кардано. http://equationsolver.intemodino.com/ru/cubic-equation.html. Интернет ресурс. Вход свободный.
3. Комбинаторика. http://webmath.exponenta.ru/s/c/algebra/content/chapter4/section3/paragraph9/theory.html. Интернет ресурс. Вход свободный.
Не нашли, что искали? Воспользуйтесь поиском по сайту:
©2015 - 2024 stydopedia.ru Все материалы защищены законодательством РФ.
|