2013-07-05 10 views
3

即時編程c中的物理(蒙特卡羅自旋磁場)模擬,遇到了一種奇怪的問題。 一個if語句只適用於某個變量的某個值。我試圖做的是,我有一個變量(bh,外部磁場),具有一定的初始值。我繼續降低它,直到它在10步內達到-bh,然後它應該開始增加,直到它再次達到+ bh,直到迭代結束。 這工作正常bh = .3,但如果我將它設置爲.1,2或1它不起作用。它開始下降,但不會停止,直到模擬結束。我的程序中沒有其他值等於.3!a if語句只能以某些值運行

我不確定要包含什麼,因爲主程序有點長。但代碼片段(無主迴路,但包括調試回聲):

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 0.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 ...」,但不知何故ç認爲對方不等於‘足夠’到BUP設置爲1 。 我做錯了什麼?

+3

由於內部舍入,不要比較浮點數是否相等。 – Duck

+0

請仔細閱讀我答案下的評論,他們提供了一些非常有用的建議。 –

回答

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

使用==來比較浮點數的結果通常不是你所期望的,因爲四捨五入。

定義EPSILON一些合理的小值,比較喜歡這個浮點數:

if (fabs(bh - bmax) < EPSILON) 
+0

啊好吧,所以我必須使用雙重,然後它應該工作?會嘗試一下,謝謝! – Nicouh

+1

使用double將無濟於事。浮點數和雙精度對於實數是有限近似的,並且不具有無限精度。 – LogicG8

+0

@Nicouh不是真的,使用'double'會導致類似的問題,你應該比較它們,如'if(fabs(bh - bmax)

3

你不應該測試與浮點變量平等。你需要在一定的容忍度內進行測試。例如:

#define EPSILON (0.000001) 
if (fabs(bh - bmax) < EPSILON) 
+0

謝謝! – Nicouh

0

正如其他人所說,你不應該==,因爲運營商seraches精確匹配比較浮動點。

即使您的數字在以十進制表示法(±.3,步長爲.03)表達時看起來非常簡單,當轉換爲內部二進制表示形式的od FP編號時,它們會導致無盡的重複位模式(類似於重複小數)。由於FP編號的大小有限,所以超出的位數會被截斷或舍入,但無論哪種情況下,它們的連續累加量可能會增加,這可能會導致預期數字的確切表示形式不斷增加。