Консультация № 175306
15.12.2009, 21:31
0.00 руб.
0 2 2
Здравствуйте
Данную задачу надо решить на С++
Тема: Численные методы
Задача: решить уравнение sinX2+cosX2-10X=0 ; Отрезок, содержащий корень [0;1] ;
Методом половинного деления ; Точное значение корня 0,1010

Обсуждение

давно
Специалист
246813
155
15.12.2009, 22:09
общий
это ответ
Здравствуйте, kalim.
Комментарии в программе
Код:
#include <iostream>
#include <cmath>
using namespace std;

int main()
{
double a, b, e, c, r, Fa, Fc;
a=0;
b=1;
e=0.1010;
locale::global(locale("russian_russia.866"));
//Метод половинного деления
do //процесс повторяется до тох пор, пока длина интервала [a,b] не станет равной либо меньшей заданной точности
{ //Вычисляем значение функции f(x) в точках a и c.
c=(a+b)/2;
Fa=sin(a*a)+cos(a*a)-10*a;
Fc=sin(c*c)+cos(c*c)-10*c;
if ((Fa*Fc)<0) b=c;//если <0, то корень находится в левой половине интервала[a,b]. Тогда отбрасываем правую половину интервала и делаем переприсвоение .
else a=c;//иначе, корень находится в правой половине интервала[a,b]. Тогда отбрасываем левую половину и делаем переприсвоение
//В обоих случаях мы получим новый интервал в 2 раза меньший предыдущего.
r=a-b;
if(r<0)r=-r; //по модулю
}while(r>=e);
wcout<<L"По методу половинного деления c="<<c<<endl;
wcout<<L"\nДля выхода нажмите любую клавишу...\n";
return 0;
}

Рад был помочь!
Неизвестный
15.12.2009, 22:45
общий
это ответ
Здравствуйте, kalim.

Мой вариант программы — в приложении.
Функция может показаться сложной, но только на первый взгляд. Она достаточно быстрая (для этого метода) — значение функции в цикле вычисляется только один раз и определяется знак результата.

Проверено в MSVC++ 6.0

Успехов!



Приложение:
// решить уравнение sinX2+cosX2-10X=0 методом половинного деления
// Отрезок, содержащий корень [0;1]
// Точное значение корня 0,1010

#include <math.h>
#include <stdio.h>

typedef double (*FUNC_X)( double );

int sign( double x )
{
return x > 0 ? 1 : x < 0 ? -1 : 0;
}

double func( double x )
{
double x2 = x*x;
return sin(x2) + cos( x2 ) - 10*x;
}


// ------------------------------------------------------------------
// Нахождение решения уравнения f(x) = 0 методом половинного деления.
// Параметры:
// f - указатель на функцию для вычисления f(x)
// a, b - границы интервала, в котором искать корень
// eps - требуемая точность
// result - найденное решение
// Функция возвращает:
// 1 - найдено точное решение ( f(result) == 0.0 )
// 0 - найдено приближенное решение с заданной точностью
// -1 - неверные границы начального интервала: f(a)*f(b) > 0
// ------------------------------------------------------------------
int bisection( FUNC_X f, double a, double b, double eps, double& result )
{
int ia = sign( f( a ));
if( ia == 0 ) {
result = a;
return 1;
}

int ib = sign( f( b ));
if( ib == 0 ) {
result = b;
return 1;
}

if( ia == ib ) // неверные параметры
return -1;

do {
double x = ( a + b )/2; // берем середину интервала
int ix = sign( f( x )); // определяем знак функции в этой точке
if( ix == 0 ) { // попали на точное решение
result = x;
return 1;
}

// какую половину берем для следующей итерации?
// проверяем знаки (сравнение целых) вместо вычисления произведения чисел с плавающей точкой
if( ix == ia )
a = x; // отбрасываем левую половину, корень находится в правой половине интервала [a,b]
else
b = x; // отбрасываем правую половину, корень находится в левой половине интервала[a,b

} while( b - a > eps ); // повторяем до тех пор, пока |a,b| > eps
result = ( a + b )/2;
return 0;
}

void main()
{
double result;
if( bisection( func, 0.0, 1.0, 1e-5, result ) < 0 )
printf( "Wrong parameters.\n" );
else
printf( "x = %f\n", result );
}
Форма ответа