3

https://www.hackerrank.com/challenges/leibniz hereに示されているように、私はライプニッツの質問に取り組んでいます。1-1/3+1/5-1/7+1/9+... を計算します。シーケンスの各要素は、a(i)=(-1)^i/(2*i+1) として定義できます。 ) i を 0 から開始します。

この質問では、第 1 項から第 n 項までを加算して結果を出力する必要があります。私のプログラムは、基本的なテスト ケースに合格します。しかし、それ以外の場合は失敗します。

私のプログラムの誤りは、数値が十分に大きい場合の精度によるものだと思います。

結果の精度を向上させる方法を提供できる人はいますか?

double leibnitz(int n) {
    double res = 0.0;
    for (int i = 1; i <= n; i++) {
        res += 1.0 / (2 * i - 1) * (i % 2 == 1 ? 1.0 : -1.0);
    }
    return res;
}
4

1 に答える 1

2

でループを開始しn、カウントダウンします。

その理由は、先頭のゼロが浮動小数点数の指数部で表されるため (「浮動小数点」という名前が付けられているため)、0 付近の小さな数値をより高い精度で加算できるため、より多くの仮数を使用できるようになるためです。したがって、より小さな部分のより正確な合計で 1 に近づくことができる場合があります。

ループは次のようになります。

for (int i = n; i >= 1; i--) {
    res += 1.0 / (2 * i - 1) * (i % 2 == 1 ? 1.0 : -1.0);
}

Jsfiddle は、順序がここで違いを生む可能性があることを示すためのより単純な問題を示しています。

http://jsfiddle.net/smt56/1

ところで:式を次のように短縮できるはずです

res += ((i % 2) * 2 - 1) / (2.0 * i - 1)
于 2013-07-07T04:50:26.657 に答える