質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.21%

f(x) = x^ 3 − 2 = 0 を二分法で解きたい

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 2,766

EUROPEAN

score 17

 前提・実現したいこと

現在プログラミング言語について学習しています。まだまだ初心者で分からないことが多すぎて困っています。そこで二分法を用いたプログラムの課題を与えられたのですがどうプログラムを変更していいのかわかりません、詳しいかたお力添えお願いいたします。

問題.方程式f(x) = x^ 3 − 2 = 0 を二分法で解きたい。

 該当のソースコード

/* bisection.h */

#include <stdio.h>
#include <math.h>
#define EPS   1.0e-10
#define K_MAX     100

void input(double *pa, double *pb);
double f(double x);
double bisection(double a, double b);
void show_each_step(double a, double b, double c, int i);

int main(void) {
    double a, b, ans;

    input(&a,&b);
    ans = bisection(a,b);
    printf("f(%.16f) = %.16f\n",ans,f(ans));

    return 0;
}

void input(double *pa, double *pb) {
    double tmp;

    do {
        printf("input a: ");
        scanf("%lf",pa);
        printf("input b: ");
        scanf("%lf",pb);
    } while (f(*pa) * f(*pb) > 0.0);
    if (*pa > *pb) {
        tmp = *pa;
        *pa = *pb;
        *pb = tmp;
    }
}

double f(double x) {
    return (x * x - 2);
}

double bisection(double a, double b) {
    double c;
    int i;
    /*step3*/
    /* to be provided */
    for (i = 1; i <= K_MAX; i++) {
        c = (a + b) / 2.0;
        show_each_step(a,b,c,i);
        /*step4の後半,step5*/
        /* to be provided */
    }

    return c;
}

int dgtof(int m) {
    int ans = 1;

    while (m >= 10) {
        ans++;
        m = m / 10;
    }

    return ans;
}

void show_each_step(double a, double b, double c, int i) {
    int dgt = dgtof(K_MAX);

    printf("<%*d> [ %.16f, %.16f ], ",dgt,i,a,b);
    printf("f(%.16f) = % .16f\n",(a+b)/2.0,f(c));
}

 補足情報(FW/ツールのバージョンなど)

/* to be provided */となっている部分を変更しなければなりません。

/*step3*/はもし |f(a)| < ε ならば a を解として終了.また,もし
|f(b)| < ε ならば b を解として終了.

/*step4*/はc = a+b/2 とし,もし |f(c)| < ε ならば c を解として終了.

step5はf(a)f(c) > 0 ならば a = c とし,そうでなければ b = c として
Step4 に戻る.

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • swordone

    2018/09/27 13:50

    そこまでわかっててなにを聞きたいのか不明ですが…あと関数違くないですか?

    キャンセル

  • EUROPEAN

    2018/09/27 14:05

    /* to be provided */となっている部分のC言語での書き方についてです。

    キャンセル

  • 退会済みユーザー

    2018/09/27 16:39

    複数のユーザーから「やってほしいことだけを記載した丸投げの質問」という意見がありました
    「質問を編集する」ボタンから編集を行い、調査したこと・試したことを記入していただくと、回答が得られやすくなります。

回答 2

checkベストアンサー

0

こんな感じでしょうか?
10桁精度で求まりました。

プログラムの答え
1.259921049902914

Wolframe Alpha の答え
x = 2^(1/3) = 1.259921049894873164767210607278228350570251464701507980081

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

#define EPS 1.0e-10  // 閾値
#define K_MAX 100  // 最大反復回数

void input(double *pa, double *pb);
double f(double x);
double bisection(double a, double b);
void show_each_step(double a, double b, double c, int i);

int main(void)
{
    double a, b, ans;

    input(&a, &b);  // 初期値を得る。
    ans = bisection(a, b);  // 2分法を実行する。
    printf("result: f(%.2f) = %.2f\n", ans, f(ans));
}

// 次を満たす初期値 x1、x2 をとる。
// (f(x1) と f(x2) の符号が異なり、かつ x1 < x2)
void input(double *x1, double *x2)
{
    do {
        printf("input a: ");
        scanf("%lf", x1);
        printf("input b: ");
        scanf("%lf", x2);
    } while (f(*x1) * f(*x2) > 0.0);
    // f(x1) と f(x2) の符号が異なるように初期値をとる。

    // 初期値は x1 < x2 となるようにする。
    if (*x1 > *x2) {
        double tmp = *x1;
        *x1 = *x2;
        *x2 = tmp;
    }
}

double f(double x)
{
    return pow(x, 3) - 2;  // x^3 - 2
}

double bisection(double a, double b)
{
    double c;
    for (int i = 0; i < K_MAX; i++)
    {
        c = (a + b) / 2.;

        if (fabs(f(c)) < EPS)
            break;  // 解が見つかった
        else if (f(a) * f(c) < 0)
            b = c;  // 解は c より右側にある
        else
            a = c;  // 解は c より左側にある

        show_each_step(a, b, c, i);
    }

    return c;
}

void show_each_step(double a, double b, double c, int i)
{
    printf("%d: [%.2f, %.2f], ", i, a, b);
    printf("f(%.2f) = %.2f\n", c, f(c));
}
input a: 0                                                                                                     
input b: 2                                                                                                     
0: [1.000000000000000, 2.000000000000000], f(1.000000000000000) = -1.000000000000000                           
1: [1.000000000000000, 1.500000000000000], f(1.500000000000000) = 1.375000000000000                            
2: [1.250000000000000, 1.500000000000000], f(1.250000000000000) = -0.046875000000000                           
3: [1.250000000000000, 1.375000000000000], f(1.375000000000000) = 0.599609375000000                            
4: [1.250000000000000, 1.312500000000000], f(1.312500000000000) = 0.260986328125000                            
5: [1.250000000000000, 1.281250000000000], f(1.281250000000000) = 0.103302001953125                            
6: [1.250000000000000, 1.265625000000000], f(1.265625000000000) = 0.027286529541016                            
7: [1.257812500000000, 1.265625000000000], f(1.257812500000000) = -0.010024547576904                           
8: [1.257812500000000, 1.261718750000000], f(1.261718750000000) = 0.008573234081268                            
9: [1.259765625000000, 1.261718750000000], f(1.259765625000000) = -0.000740073621273                           
10: [1.259765625000000, 1.260742187500000], f(1.260742187500000) = 0.003912973217666                           
11: [1.259765625000000, 1.260253906250000], f(1.260253906250000) = 0.001585548394360                           
12: [1.259765625000000, 1.260009765625000], f(1.260009765625000) = 0.000422512079240                           
13: [1.259887695312500, 1.260009765625000], f(1.259887695312500) = -0.000158837092386                          
14: [1.259887695312500, 1.259948730468750], f(1.259948730468750) = 0.000131823412403                           
15: [1.259918212890625, 1.259948730468750], f(1.259918212890625) = -0.000013510360162                          
16: [1.259918212890625, 1.259933471679688], f(1.259933471679688) = 0.000059155646067                           
17: [1.259918212890625, 1.259925842285156], f(1.259925842285156) = 0.000022822422940                           
18: [1.259918212890625, 1.259922027587891], f(1.259922027587891) = 0.000004655976386                           
19: [1.259920120239258, 1.259922027587891], f(1.259920120239258) = -0.000004427205639                          
20: [1.259920120239258, 1.259921073913574], f(1.259921073913574) = 0.000000114381936                           
21: [1.259920597076416, 1.259921073913574], f(1.259920597076416) = -0.000002156412711                          
22: [1.259920835494995, 1.259921073913574], f(1.259920835494995) = -0.000001021015602                          
23: [1.259920954704285, 1.259921073913574], f(1.259920954704285) = -0.000000453316887                          
24: [1.259921014308929, 1.259921073913574], f(1.259921014308929) = -0.000000169467489                          
25: [1.259921044111252, 1.259921073913574], f(1.259921044111252) = -0.000000027542780                          
26: [1.259921044111252, 1.259921059012413], f(1.259921059012413) = 0.000000043419577                           
27: [1.259921044111252, 1.259921051561832], f(1.259921051561832) = 0.000000007938399                           
28: [1.259921047836542, 1.259921051561832], f(1.259921047836542) = -0.000000009802191                          
29: [1.259921049699187, 1.259921051561832], f(1.259921049699187) = -0.000000000931896                          
30: [1.259921049699187, 1.259921050630510], f(1.259921050630510) = 0.000000003503251                           
31: [1.259921049699187, 1.259921050164849], f(1.259921050164849) = 0.000000001285678                           
32: [1.259921049699187, 1.259921049932018], f(1.259921049932018) = 0.000000000176891                           
33: [1.259921049815603, 1.259921049932018], f(1.259921049815603) = -0.000000000377502                          
34: [1.259921049873810, 1.259921049932018], f(1.259921049873810) = -0.000000000100306                          
result: f(1.259921049902914) = 0.000000000038292    

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

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

double f(double x);

int main(void)
{
    double a = 2,b = 1;
    double c = (a + b) / 2.0;

    while(fabs(f(c)) > pow(10,-15)){
        if(f(c) > 0){
            a = c;
        }
        else if(f(c) < 0){
            b = c;
        }
        else{
            break;
        }
        c = (a + b) / 2.0;
    }
    printf("%.15f",c);
    return 0;

}

double f(double x)
{
    return pow(x,3) - 2;
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.21%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる