Форум программистов, компьютерный форум CyberForum.ru

Найти корень уравнения методом половинного деления - C++

Восстановить пароль Регистрация
 
nomri
0 / 0 / 0
Регистрация: 16.01.2013
Сообщений: 7
01.07.2013, 10:14     Найти корень уравнения методом половинного деления #1
Найти корень уравнения методом половинного деления x^2-1/2=0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
01.07.2013, 10:14     Найти корень уравнения методом половинного деления
Посмотрите здесь:

Методом деления отрезка пополам и методом итераций найти прибли-женное значение корня уравнения C++
C++ Описать рекурсивную функцию, которая методом деления отрезка пополам находит корень уравнения
C++ Найти корень уравнения методом касательных
Найти корень уравнения методом касательных C++
C++ Вычислить корень уравнения на отрезке [a; b] с точностью eps=0.000001, методом половинного деления
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
vxg
Модератор
 Аватар для vxg
2662 / 1673 / 157
Регистрация: 13.01.2012
Сообщений: 6,234
01.07.2013, 13:17     Найти корень уравнения методом половинного деления #2
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
//------------------------------------------------------------------------------
class bad_bracket_end_points {};
class bad_initial_point {};
class too_many_iteration {};
//------------------------------------------------------------------------------
long root_iteration = 1000000;
//------------------------------------------------------------------------------
double dichotomic_root
(
    double (* const y)(const double &x),
    double x_min, double x_max,
    const double &dx, const double &dy
)
{
    double y_x_min = y(x_min);
    double y_x_max = y(x_max);
 
    double x_mid, y_x_mid;
 
    if (x_min >= x_max || (y_x_min > 0) == (y_x_max > 0))
        throw bad_bracket_end_points();
 
    long k = 0;
 
    do
    {
        x_mid = (x_min + x_max) / 2;
        y_x_mid = y(x_mid);
 
        if ((y_x_min > 0) == (y_x_mid > 0))
            x_min = x_mid;
        else
            x_max = x_mid;
 
        k++;
        if (k > root_iteration) throw too_many_iteration();
    }
    while (x_max - x_min > dx && fabs(y_x_mid) > dy);
 
    return x_mid;
}
nomri
0 / 0 / 0
Регистрация: 16.01.2013
Сообщений: 7
01.07.2013, 14:16  [ТС]     Найти корень уравнения методом половинного деления #3
а попроще никак? вот похожая программа на паскале
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
uses crt;
const e=0.00001;
function F(x:real):real;
begin
F:=cos(x)-sqrt(x);
end;
var a,b,c,x:real;
begin
a:=0.0;
b:=1.0;
writeln('Решение уравнения cos(x)-sqrt(x)=0');
writeln('на интервале [',a:0:1,';',b:0:1,'] с погрешностью ',e:0:5);
repeat
 c:=(a+b)/2;
 if F(a)*F(c)<=0 then b:=c
 else a:=c;
 x:=(b+a)/2;
until abs(a-b)<e;
writeln('x=',x:0:5,' F(x)=',F(x):0:6);
end.
-=ЮрА=-
Заблокирован
Автор FAQ
01.07.2013, 14:41     Найти корень уравнения методом половинного деления #4
nomri, твой паскалевский вариант не учитывает тот факт что пользователь может ввести некорректный интервал, потому проверка завершения итерационного процесса должна содержать ещё условие f(a)*f(b) < 0 - которое говорит что на а...b есть корень
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <cmath>
#include <iostream>
using namespace std;
 
double f(double x)
{
    return x*x - 0.5;
}
 
int main()
{
    double a, b, e, x;
    cout<<"Localize the root interval [a;b] :"<<endl;
    cout<<"a = ";cin>>a;cin.get();
    cout<<"b = ";cin>>b;cin.get();
    cout<<"Calc error e = ";cin>>e;cin.get();
    do
    {
        x = (a + b) / 2;
        if(f(a)*f(x) < 0)
            b = x;
        else
        if(f(x)*f(b) < 0)
            a = x;
        cout<<"\rx = "<<x<<" f(x) = "<<f(x);
        cout<<" root correct : ";
        if( f(a)*f(b) < 0 )
             cout<<"yes";
        else
            cout<<"no";
        cout<<"\t\t";
    }
    while(fabs(a - b) > e && f(a)*f(b) < 0);
    cin.get();
    return 0;
}
Миниатюры
Найти корень уравнения методом половинного деления   Найти корень уравнения методом половинного деления  
Olivеr
 Аватар для Olivеr
411 / 407 / 13
Регистрация: 06.10.2011
Сообщений: 830
01.07.2013, 15:11     Найти корень уравнения методом половинного деления #5
Вот. Нарыл у себя. Решает уравнение 2x^2 - 0.5^x - 3
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <cmath>
#include <functional>
#include <iomanip>
using namespace std;
 
double solve(function<double (double)> f, double a, double b, double eps)
{
    if (a > b) swap(a, b);
    while ( abs(a - b) > eps ) {
        double x = (a + b) / 2.0;
        if ( f(a) * f(x) < 0 )
            b = x;
        else a = x;
    }
    return (a + b) / 2.0;
}
 
int main()
{
    auto f1 = [](double x)->double { return 2 * pow(x, 2.0) - pow(0.5, x) - 3; };
    cout << fixed << setprecision(11) << solve( f1, 1, 2, 0.00001 );
    return 0;
}
-=ЮрА=-
Заблокирован
Автор FAQ
01.07.2013, 15:21     Найти корень уравнения методом половинного деления #6
Olivеr, твой код именно яркий пример моих слов
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
что пользователь может ввести некорректный интервал, потому проверка завершения итерационного процесса должна содержать ещё условие f(a)*f(b) < 0 - которое говорит что на а...b есть корень
http://ideone.com/r6n5NY

Цитата Сообщение от Olivеr Посмотреть сообщение
while ( abs(a - b) > eps )
- этого не достатоно
Корня на промежутке 1,2 не существует потому 1.30475997925 - это не решение.
Решением для данного интервала будет ответ - некорректный интервал либо корень
Миниатюры
Найти корень уравнения методом половинного деления  
-=ЮрА=-
01.07.2013, 15:25
  #7

Не по теме:

Olivеr, я не заметил что у тебя функция иная, но смысл тот же, нужна доп проверка

Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
while(fabs(a - b) > e && f(a)*f(b) < 0);

Olivеr
 Аватар для Olivеr
411 / 407 / 13
Регистрация: 06.10.2011
Сообщений: 830
01.07.2013, 15:48     Найти корень уравнения методом половинного деления #8
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение

Не по теме:

Olivеr, я не заметил что у тебя функция иная, но смысл тот же, нужна доп проверка

Не по теме:

-=ЮрА=-, я считаю, что программист сам должен следить за данными которые загоняет в функцию.

-=ЮрА=-
01.07.2013, 15:52
  #9

Не по теме:

Цитата Сообщение от Olivеr Посмотреть сообщение
-=ЮрА=-, я считаю, что программист сам должен следить за данными которые загоняет в функцию.
- программист да, юзер в большинстве случаев чайник, который даже цифру ввести может с ошибкой не то чтобы интервал верный взять.
Впрочем думаю автору темы уже точно есть с чем работать.

vxg
Модератор
 Аватар для vxg
2662 / 1673 / 157
Регистрация: 13.01.2012
Сообщений: 6,234
01.07.2013, 16:32     Найти корень уравнения методом половинного деления #10
Цитата Сообщение от nomri Посмотреть сообщение
а попроще никак?
не понимаю что вас не устраивает. это процедура решающая уравнение. вы передаете туда указатель на функцию и получаете результат. или исключение. проще только на бумаге. аналитически.
isaak
101 / 38 / 9
Регистрация: 17.10.2010
Сообщений: 634
02.07.2013, 13:52     Найти корень уравнения методом половинного деления #11
-=ЮрА=- не мог бы ты на примере кода Olivеr показать проверку корректности ввода интервала while(fabs(a - b) > e && f(a)*f(b) < 0). Я сделал как ты советуешь, но ни какой проверки не происходит.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <cmath>
#include <functional>
#include <iomanip>
using namespace std;
 
double solve(function<double (double)> f, double a, double b, double eps)
{
    if (a > b) swap(a, b);
    while(fabs(a - b) > eps && f(a)*f(b) < 0) {
        double x = (a + b) / 2.0;
        if ( f(a) * f(x) < 0 )
            b = x;
        else a = x;
    }
    return (a + b) / 2.0;
}
 
int main()
{
    /*auto f1 = [](double x)->double { return 2 * pow(x, 2.0) - pow(0.5, x) - 3; };*/
    auto f1 = [](double x)->double { return x*x - 0.5; };
    cout << fixed << setprecision(11) << solve( f1, 0, 1, 0.001 );
    cin.get();
    return 0;
}
Если не сложно, заранее огромное спасибо.
Olivеr
 Аватар для Olivеr
411 / 407 / 13
Регистрация: 06.10.2011
Сообщений: 830
02.07.2013, 14:23     Найти корень уравнения методом половинного деления #12
Думаю так можно
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
#include <cmath>
#include <functional>
#include <iomanip>
using namespace std;
 
double solve(function<double (double)> f, double a, double b, double eps)
{
    if (a > b) swap(a, b);
    if (f(a) * f(b) >= 0)
        throw invalid_argument ("Invalid range");
    while(abs(a - b) > eps) {
        double x = (a + b) / 2.0;
        if ( f(a) * f(x) < 0 )
            b = x;
        else a = x;
    }
    return (a + b) / 2.0;
}
 
int main()
{
    try {
        //auto f1 = [](double x)->double { return 2 * pow(x, 2.0) - pow(0.5, x) - 3; };
        auto f1 = [](double x)->double { return x*x - 0.5; };
        double x = solve( f1, 0, 1, 0.001 );
        cout << fixed << setprecision(11) << "x = " << x << endl;
        cout << "f(x) = " << f1(x);
    } catch (const exception &e) {
        cerr << e.what() << endl;
    }
    cin.get();
    return 0;
}
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
02.07.2013, 14:53     Найти корень уравнения методом половинного деления
Еще ссылки по теме:

Решение уравнения методом половинного деления C++
C++ Решение уравнения методом половинного деления
C++ Найти корни уравнения методом половинного деления

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
-=ЮрА=-
Заблокирован
Автор FAQ
02.07.2013, 14:53     Найти корень уравнения методом половинного деления #13
isaak, используй мой код мне не нра С+11
Цитата Сообщение от isaak Посмотреть сообщение
Я сделал как ты советуешь, но ни какой проверки не происходит.
- как это не происходит - она происходит, надо только возвращать во внешний блок результат проверки (как это сделано у меня пару постов назад)
Касательно кода Olivеr - вот линк на реализацию с проверкой http://ideone.com/K4BOAg

Не по теме:

(isaak, признаюсь честно, что не люблю давать примеры чего либо по чужим кодам, впредь учти это в своих просьбах. Художник-мастер пишет по своему холсту а не по чужому, просить его поправить что либо чужое равносильно тому что подойти и облить кислотой его картину)

Yandex
Объявления
02.07.2013, 14:53     Найти корень уравнения методом половинного деления
Ответ Создать тему
Опции темы

Текущее время: 12:33. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru