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 );
}