1

ここで説明されているように、ニュートンの方法を使用してこの作業を取得しようとしました:次のコードを使用したwikiですが、問題は、小数点以下 16 桁までしか正確な結果が得られないことです。繰り返し回数を増やしてみましたが、結果は同じです。私は1の最初の推測から始めました。では、どうすれば回答の精度を向上させることができますか(小数点以下100桁以上)? ありがとう。コード:

double x0,x1;
#define n 2
double f(double x0)
{
    return ((x0*x0)-n);
}
double firstDerv(double x0)
{
    return 2.0*x0;
}
int main()
{
    x0 = n/2.0;
    int i;
    for(i=0;i<40000;i++)
    {
        x1=x0-(f(x0)/((firstDerv(x0))));
        x0=x1;
    }
    printf("%.100lf\n",x1);
    return 0;
}
4

4 に答える 4

4

精度が制限された浮動小数点の問題を回避するために、ニュートン法を使用して、sqr(2) のより適切な近似である有理数 (a と b の整数による a/b) を反復ごとに見つけることもできます。

x=a/b が最後の反復から返された値である場合、ニュートン法は、新しい推定値 y=c/d は次のようになります。

y = x/2 + 1/x = a/2b + b/a = (a^2+2b^2)(2ab)

それで:

c= a^2 + 2b^2

d=2ab

精度は反復ごとに 2 倍になります。分子と分母が急速に増加するため、到達できる精度にはまだ制限がありますが、おそらく、大きな整数の実装を見つける (または自分で作成する) 方が、任意精度の浮動小数点の実装を見つけるよりも簡単です。また、小数に本当に興味がある場合、この回答は役に立ちません。sqr(2) の非常に正確な見積もりが得られます。

アルゴリズムの a/b の反復のみ:

1/1、3/2、17/12、577/408、665857/470832。

665857/470832 は sqr(2) を 1.59e-12 の誤差で近似します。エラーは 1/a^2 のオーダーのままであるため、a と b を long として実装すると、1e-37 の精度が得られます。

于 2011-12-14T14:59:55.703 に答える
2

そのアプローチではそれを行うことはできません。double には、100 桁の精度を得るのに十分なビットがありません。GMPなどの任意精度のライブラリの使用を検討してください。

于 2011-12-14T13:41:39.097 に答える
2

現在のマシンの浮動小数点数はIEEE754であり、精度が制限されています (約 15 桁)。

さらに精度が必要な場合は、GMPなどのソフトウェア ライブラリによって (ゆっくりと) 提供されるbignumが必要になります。

bignum を使用して、言語と実装でプログラムをコーディングすることもできます。

于 2011-12-14T13:40:45.230 に答える
0

おそらくこれは、浮動小数点数がコンピューターによって m*10^e 形式で近似されるためです。m と e は有限の桁数で構成されているため、すべての数値を絶対精度で近似することはできません。

0.333333333333333 である 1/3 を考えてください...

于 2011-12-14T13:41:40.083 に答える