2011-01-23 161 views
1

我必须从0循环到步骤0.5。但是,当值为5时,周期应该颠倒。正确的循环循环

bool forward = true; 
int counter = 0; 
float val = 5.0f; 

// And somewhere in global app cycle: 
if (val <= 0.0 && forward) forward = false; 
if (forward) val -= .5f; 

if (val >= 5.0 && !forward) forward = true; 
if (!forward) val += .5f; 

但是结果有时候是负数,我认为这有点难看。

0.2 
0.18 
0.16 
0.14 
0.12 
0.1 
0.08 
0.06 
0.04 
0.02 
2.98023e-08 
-0.02 
2.98023e-08 
0.02 
0.04 
0.06 
0.08 
0.1 
0.12 
0.14 
0.16 
0.18 
0.2 
0.2 
0.18 
+1

你是什么意思“的结果有时是负数”?请举例说明你正在观察的内容。 – 2011-01-23 11:58:44

回答

4

您遇到的问题是0.2无法在浮点中精确表示。所以当你写val -= 0.2时,你真正在做的是val -= 0.20000000298023224;。因此,你积累了错误。

解决方法是不使用浮点来控制循环。改为使用int,然后乘以常数得到val。例如:

int inc = -1; 
int i = 10; 

while (whatever) 
{ 
    if (i == 0) inc = +1; 
    if (i == 10) inc = -1; 

    i += inc; 

    float val = i * 0.02; 
} 
0

| val - 5.0 | < eps & & | val - 0 | < eps其中| |在你的情况下,fabsf()我猜

也记住,当两个几乎相等的(浮点表示)值被减去时,精度会有一些损失。

2

使用整数表示从0到10与步骤1的循环或从0到50与步骤5的循环。Float可以是0.00000012,因此它不小于或等于0.0。 您可以根据需要计算循环变量中的浮点数。

0

不是指定每次移动的距离,可以指定分割数量吗? 这样一来,你的价值永远不会漂移由于精度/舍入误差 EG:

void Step(float from, float to, int divisions) 
{ 
    float range = to - from; 
    float perDivision = range/divisions; 

    int i = 0; 
    for(;;) 
    { 
     for(; i < divisions; ++i) 
     { 
      UseCurrentValue(from + (i * perDivision)); 
     } 
     for(; i > 0; --i) 
     { 
      UseCurrentValue(from + (i * perDivision)); 
     } 
    } 
} 

void UseCurrentValue(float val) 
{ 
    // Do something with val here. 
}