こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

c言語プログラミングについて

ニュートン法でx^2-2の根を初期値2、試行回数を200回までで求めるプログラムを作成しているのですがうまくいきません。
どなたかご教授お願いいたします。
#include<stdio.h>
#include<math.h>
int main()
{
int i;
int N = 200;
double x = 2.0;
double xnew;
double eps = 1e-16;
for (i = 0; i < N; i++) {
xnew = x - ( x * x - 2.0 ) / 2.0 * x;
if (fabs(x - xnew) < eps)
break;
x = xnew;
}
printf("x=%.20lf\n", xnew);
return(0);
}

投稿日時 - 2020-10-20 10:54:15

QNo.9813439

困ってます

質問者が選んだベストアンサー

perlに移植してやってみたところ、式のミスだったようです。

>xnew = x - ( x * x - 2.0 ) / 2.0 * x;

こちら、掛け算と割り算は同じ優先順位ですので、後ろの方も、左から計算されています。

つまり次の式と同値です。

>>xnew = x - (( x * x - 2.0 ) / 2.0) * x;

本当は当然、

>>xnew = x - ( x * x - 2.0 ) / (2.0 * x);

のつもりでしたよね。
その様に直すと、ちゃんと√2っぽい数字になりました。

カッコを使わなければ、

>>xnew = x - ( x * x - 2.0 ) / 2.0 / x;

としてもいいです。

----

なお確かに、No.1さんの指摘通り、

>double eps = 1e-16;

というのは、eps値として小さすぎるかもしれません。
この値自身としては表現できるのですが、比較対象が有効数字16桁なので、存在しない17桁目と比較してしまっているようです。
ループ内でもprintfしてみたところ、200回全部回ってしまいました。

>double eps = 1e-15;

としたところ、数回でループを抜けました。

投稿日時 - 2020-10-20 11:49:46

お礼

epsの値の検証までしていただきありがとうございます。
具体的な修正をしていただいたこちらをベストアンサーにさせて頂きます。

投稿日時 - 2020-10-20 12:09:30

ANo.2

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(2)

ANo.1

> double eps = 1e-16;

doubleの精度は15桁程度ですから、小さすぎませんか?

投稿日時 - 2020-10-20 11:30:06

補足

精度についてのご指摘ありがとうございます。
また、printfの表示結果がおそらく1.414...ほどになるになるはずなのですが0.000...となってしまうのですが、修正箇所を教えていただきたいです。

投稿日時 - 2020-10-20 11:51:37

お礼

ご回答ありがとうございます。
精度の桁数等まだまだ勉強不足の点がございました。
これを機にまた勉強しなおさせていただきます。

投稿日時 - 2020-10-20 12:03:26

あなたにオススメの質問