if语句仅适用于某些值

时间:2013-07-05 00:41:02

标签: c if-statement floating-point comparison

我在c中编程物理(蒙特卡罗旋转磁场)模拟并遇到了一种奇怪的问题。 if语句仅适用于一个变量的特定值。我试图做的是我有一个具有一定初始值的变量(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.我做错了什么?

3 个答案:

答案 0 :(得分:4)

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

使用==来比较浮点数通常不会因为四舍五入而产生预期结果。

EPSILON定义为一个合理的小值并比较浮点数,如下所示:

if (fabs(bh - bmax) < EPSILON)

答案 1 :(得分:3)

您永远不应该使用浮点变量测试相等性。你需要在一定的容忍范围内进行测试例如:

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

答案 2 :(得分:0)

正如其他人所说的那样,你不应该将浮点数与==进行比较,因为该运算符会进行精确匹配。

即使你的数字看起来很简单,用十进制表示法表示(±.3,步长为±.03),当翻译成内部二进制表示od FP数字时,它们会产生无穷无尽的重复位模式(类似于重复小数点)。由于FP数量的大小有限,超出的比特要么被截断,要么被舍入,但在任何一种情况下,它们的连续累积可能会增加,这可能会引起预期数字精确表示的偏差。