2

こんにちは、c++ の ceil 関数に問題があります。

ポイントの規則的なグリッドがあり、それに対して補間を実行して、一連のポイントの Z 値を計算する必要があります。

そのためには、計算されたポイントごとに、グリッド上の最も近いポイントを取得する必要があります。私はこのようにします:

y1 = dy*floor(p.y/dy);
y2 = dy*ceil(p.y/dy);

ここで、dy はグリッドの 2 点間のスペースです。(y1、py、dy は double) を使用して結果を表示すると、

cout << static_cast<double>(p.y/dy) << ": " << y1 << ", " << y2 << endl;

私はこれらの奇妙な結果を得ました:

0: 0, 0
1: 0.1, 0.1
2: 0.2, 0.2
3: 0.3, 0.4

最初の 3 つの結果は OK ですが、最後の結果は正しくなく、アサーションが失敗します。

この奇妙なエラーがどこで発生したか、およびそれを回避する方法を知りたいです。ありがとう。

私の英語で申し訳ありません

編集

dy = 0.1 で関数を呼び出しますが、実行中に次の値 dy = 0.10000000000000001 を取得します。py は次のように初期化されます。

 const uint N = round((x2 - x1) / dx2);
 const uint M = round((y2 - y1) / dy2);

 double p = persistence;
 double n = number_of_octaves;

 // generation of the points where the perlin noise is generated
 std::vector<Vertex3d> ret;
 std::vector<Vertex3d> dummy;
 for (uint i=0;i<=N;++i)
 {
        for (uint j=0;j<=M;++j)
        {
                ret.push_back({.x = i*dx2, .y=j*dy2, .z=0});
                dummy.push_back({.x = i*dx2, .y=j*dy2, .z=0});
        }
 }

ここで、x1 = 0 および x2 = 1 (gdb による)

4

3 に答える 3

1

浮動小数点演算を使用している場合、浮動小数点計算は不正確であるため、通常、結果が正確に整数であることに依存するべきではありません。これに依存しないように、おそらくコードを再設計する必要があります。

これは、浮動小数点演算の古典的な議論です

于 2013-03-08T10:24:14.370 に答える
1

あなたの結果を考えると、dyに等しいと思います0.1

あなたの結果は間違っていません。もしあなたが持っているなら0.3 < p.y < 0.4、あなたは3 < p.y/dy < 4そうするceilでしょう。4floor3

コードのどこかでp.y0.3 または 0.4 に設定しているため、混乱している可能性があります。float はそれほど正確ではないことを知っておく必要があります。これは、設定したとしても、またはそのようなp.y = 0.3値を持つことができ、問題が発生することを意味します。0.30000001

于 2013-03-08T10:24:49.273 に答える
-1

これは、浮動小数点演算の丸め誤差の場合のように見えます。

最後のケースの結果が 3.00000000000001 であるため、その上限は 3 ではなく 4 である可能性があります (その後、0.1 が乗算されます)。

于 2013-03-08T10:24:29.840 に答える