3

Cで物理(モンテカルロスピン磁場)シミュレーションをプログラミングしていて、一種の奇妙な問題に遭遇しました。if ステートメントは、1 つの変数の特定の値に対してのみ機能します。私がやろうとしているのは、特定の初期値を持つ変数 (bh、外部磁場) があることです。10 ステップ以内に -bh に達するまで減少させ続け、その後 +bh に再び達するまで増加し始め、反復が終了するまで続けます。これは bh=.3 では正常に機能しますが、.1、.2、または 1 に設定すると機能しません。減少し始めますが、シミュレーションが終了するまで止まりません。私のプログラムには、.3 に等しい他の値はありません!

メインプログラムは少し長いので、何を含めればよいかわかりません。ただし、コード フラグメントは次のとおりです (メイン ループはありませんが、デバッグ エコーが含まれます)。

 float bh;  float bmax;
 bh=.3; bmax=bh;

if (bup==1) {
     printf("BUP=1, BFeld = %.2f\n",bh);
     bh = bh + bmax/10;
     if (bh == bmax) { bup=0; }
}
if (bup==0) {
    printf("BUP=0, BFeld = %.2f, %.2f = bmin\n",bh,-bmax);
    bh = bh - bmax/10;
    if (bh == -bmax) { bup=1; }
}

デバッグ出力に関して得られるのは、bh=.3 の場合です

[...]
BUP=0, BFeld = -0.24, -0.30 = bmin
BUP=0, BFeld = -0.27, -0.30 = bmin
BUP=1, BFeld = -0.30
BUP=1, BFeld = -0.27
BUP=1, BFeld = -0.24
[...]

しかし、bh を 1 に設定すると、

[...]
BUP=0, BFeld = -0.80, -1.00 = bmin
BUP=0, BFeld = -0.90, -1.00 = bmin
BUP=0, BFeld = -1.00, -1.00 = bmin
BUP=0, BFeld = -1.10, -1.00 = bmin
BUP=0, BFeld = -1.20, -1.00 = bmin
BUP=0, BFeld = -1.30, -1.00 = bmin
[...]

そのため、デバッグ出力には「...-1.00、-1.00 ...」という行さえ表示されますが、どういうわけかcは、bupを1に設定するのに「十分」ではないと考えています。

4

3 に答える 3

4
if (bh == bmax) { bup=1; }

を使用==して浮動小数点数を比較すると、通常、丸めが原因で期待どおりの結果が得られません。

妥当な小さな値として定義し、次EPSILONのように浮動小数点数を比較します。

if (fabs(bh - bmax) < EPSILON)
于 2013-07-05T00:45:36.680 に答える
3

浮動小数点変数との等価性を決してテストしないでください。許容範囲内でテストする必要があります。例えば:

#define EPSILON (0.000001)
if (fabs(bh - bmax) < EPSILON)
于 2013-07-05T00:48:03.760 に答える