1

重複の可能性:
「for( i = 0.1 ; i != 1.0 ; i += 0.1)」が i = 1.0 で壊れないのはなぜですか?

数値 (実数) 間隔 [x, y] があります。次のようなものを使用して反復する必要があります。

nr = 0;
for (i = x; i <= y; i += step) //step is a small double value
    nr++;

[-1, 1] のステップが 0.001 の場合、nr が 2001 (-1.000 ... 0.999 1.000) であることは明らかですが、nr = 2000 と計算されます (調査したところ、最後の比較に失敗しました: 0.999 + 0.001 > 1.000)。

正確な nr 値を計算するにはどうすればよいですか?

4

4 に答える 4

3

float と double は本質的に不正確であるため、整数を使用してこれを行うか、不正確で満足する必要があります*。あなたのコードは、C 言語仕様に従って正確に動作しています。float と double は、正確な精度が必要な状況で使用するのは安全ではありません。

それ以外は、要件が何であるかに関する質問でより多くの情報が必要です。が温度の場合nr、正確な値を計算するには、存在しないか存在できない物理学を使用する必要があります (私は物理学者ではないので、わかりません)。が実際に不合理な値である場合stepは、切り上げまたは切り捨てを行う必要があります。呼び出しとどちらが正しいかは、ビジネス ロジックの要件によって異なります。合理的で丸めが必要ない場合は、最小公倍数を掛けてints (または C などの分数クラス) を使用する必要があります。

*コメントごとに floats/doubles は、分数の分母が 2 の累乗である場合に正確です。強制stepyてこれに準拠することができれば、問題はある程度クリアになりますが、step均等に分割されない場合はy、行う必要があります。上記とまったく同じビジネスロジック処理。

于 2012-12-06T20:09:12.150 に答える
0

発生している問題は、浮動小数点数 (floatまたはdouble) が正確に格納されていないため、メモリ内の表現が正確ではないことが多いということです。

したがって、2 つの選択肢があります。正確な数値を使用するか、ループの回数に整数を使用して値を計算します。

これは次のように行うことができます。

int numberOfIntervals = 2000;
double lowestValue = -1.0;
for (loop = 0; loop <= numberOfIntervals; ++loop)
{
    double v = (0.001 * loop ) + lowestValue;
}
于 2012-12-06T20:12:08.240 に答える
0
int nsteps = (int)((y-x)/step);
for(int i=0; nsteps; ++i){
   double v = x + (i*step);  // use v in your calculations
}
于 2012-12-06T20:12:31.403 に答える
-1

2 進浮動小数点が不正確であるというのは正しくありません。真のことは、内容が異なる (正および/または負の) 2 の累乗の合計に一致する数値の場合、値は正確になるということです。明らかに、10 進数は 10 のべき乗の合計に準拠するため、正確ではありません。基数 4、8、および 16 は、2 の倍数であるため適合します。

かなり前にこの回答を投稿しましたが、浮動小数点数がどれだけ正確かについてのヒントが得られます。また、2 の負の累乗を足して分数を組み立てる方法も確認できます。

問題を解決する方法については、必要なツールがあります。アルゴリズムが適合しない場合は、適合させることができます。

于 2012-12-06T20:32:26.543 に答える