0

重複の可能性:
浮動小数点数の精度の問題への対処

私はOpenGlアニメーションを作成しており、float変数「time」を使用して時間を追跡しています。「time」変数を0.01ずつインクリメントしています。「time」が整数値に達するたびに満たす必要がある特定の条件があります。問題は、特定の時間が経過すると、floatインクリメントが奇妙な動作を示すことです。time = 0から開始し、「time」が0.83に達した後、次の値は0.839999であることがわかります。これは浮動小数点の精度に関連している可能性があるので、double / long doubleを使用してみましたが、値1.00に到達する代わりに、コードが値1.0000007に到達していることがわかりました。

「0.01」ではなく「0.01f」ずつインクリメントしてみましたが、うまくいきませんでした。これはVisualStudioのバグですか、それとも間違った方法で行っていますか?コードを投稿することはできますが、ある場所で「時間」を割り当て、他の場所で使用されているだけなので、あまり役に立たないと思います。

4

3 に答える 3

4

何をしているのかを正確に理解していない限り、浮動小数点値が等しいかどうかを比較しないでください。この目的には整数(おそらくミリ秒の整数)を使用することを強くお勧めします。

詳細については、すべてのコンピューター科学者が浮動小数点演算について知っておくべきことを参照してください。

浮動小数点は固定精度形式です。これは、固定精度フォーマットに固有の制限です。

たとえば、小数点以下6桁の精度を使用したとします。3分の1はです.333333。しかし、3分の1を3回追加すると、1.999999ではなくが得られます。これが獣の性質です。

于 2012-12-04T04:10:04.217 に答える
2

これを正確に推奨しているわけではありませんが、問題は、0.1を正確にdoubleとして表すことができないことです。1.0にすることができます。したがって、タイムステップを2の(負の)累乗にすると、違いがわかります。実例として:

    double delta = 1.0 / 8;
    int stopper = 10;
    int nextInt = 1;
    for (double t = 0; t <= stopper; t += delta)
    {
        if (t == nextInt)
        {
            std::cout << "int ";
            ++nextInt;
        }
        else 
            std::cout << "    ";
        std::cout << t << std::endl;
    }
于 2012-12-04T04:24:54.823 に答える
1

各増分の後に「時間」を丸めて、適切な値を維持していることを確認します。

そんな感じ:

double round(double value, double precision)
{
    return floor(value / precision + 0.5) * precision;
}
time = round(time + 0.1, 0.1);
于 2012-12-04T04:18:40.153 に答える