[ad_1]
どのように機能するのか説明してください。 プログラムでは整数を加算した場合にのみ正しい結果が得られますが、私のタスクでは double 型を使用したいと考えています。
作業オプション:
`
for (int i = -10000; i < 10000; i++) { formula = s1 / (v1 + k) + s2; if (formula == 0) { break; } k += 1; }
結果:3.000000
`
正しく動作しません:
`
for (int i = -10000; i < 10000; i++) { formula = s1 / (v1 + k) + s2; if (formula == 0) { break; } k += 0.00001; }
結果:0.200000
`
私が試したこと:
私のプログラムではより正確な結果が必要なので、int 型は使用できません。
解決策 1
ステップ 1 は変数を確認することです formula
、 s1
、 s2
、 v1
、 そして k
すべて double 型です。 実際にはすべてが double である必要はありませんが、結果を確認したいとします (formula
) は double であり、除算です しなければならない ダブルスで行われます。 整数の結果では、ほぼ確実に誤った結果が得られます。
ステップ 2 は、double 値との等価比較に注意することです。つまり、 formula
はゼロです。 このための通常の手法は、「十分に近い」ことを意味するイプシロン値を定義し、それと比較することです。 以下に例を示します。
const double epsilon = 1.0E-9; // do calculations here double delta = fabs( formula ); if( delta < epsilon ) break;
これにより、for ループから抜け出すことができます。 formula
は -1E-9 から +1E-9 までの範囲にあります。 必要な計算許容範囲内であれば、イプシロンに 1.0E-6 または他の値を使用できます。
解決策 2
ここで注意すべき点がいくつかあります。 ループごとに変数 k のみが変更されるようです。
for (int i = -10000; i < 10000; i++) { formula = s1 / (v1 + k) + s2; if (formula == 0) { break; } k += 0.00001; }
残念ながら、値 k += 0.00001 は float (または double) として正確に格納できないため、コンパイラは通常、最も近い値を使用します。 ここで、これらの完全に一致しない double 数値を合計すると、合計の誤差はループごとに増加します。
現在、問題を解決する方法はいくつかあります。
1. 常に加算し続けるのではなく、スライス インデックスを 1 回乗算する方が精度が大幅に向上します。
2. 2 つの浮動小数点を直接比較するのではなく、差をチェックする方が良いでしょう。差は 0 にならないことがよくありますが、指定された値を下回るはずです。
精度を高めるために float の代わりに double を使用すると、問題が変わるだけで、解決されません。
[ad_2]
コメント