2011-01-23 203 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. 
}