Reputation: 64356
I have to cycle from 0 to 5 with step 0.5. But the cycle should be reversed when the value is 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;
But the result is sometimes negative numbers and, I think, that's a bit ugly code.
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
Upvotes: 1
Views: 680
Reputation: 272687
The problem you are experiencing is that 0.2
cannot be exactly represented in floating-point. So when you write val -= 0.2
, what you're really doing is val -= 0.20000000298023224;
. Therefore, you accumulate errors.
The solution is to not use floating-point to control your loop. Use an int
instead, and multiply by a constant to get val
. e.g.:
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;
}
Upvotes: 4
Reputation: 60411
Instead of specifying the distance to move each time, could the number of divisions be specified? This way, your value won't ever drift due to precision/rounding errors 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.
}
Upvotes: 0
Reputation:
|val - 5.0| < eps && |val - 0 | < eps where | | in your case fabsf() i guess
also keep in mind that there is some loss in precision whenever two almost equal (floating point representation) values are subtracted.
Upvotes: 0
Reputation: 11011
Use integers for such cycles from 0 to 10 with step 1 or from 0 to 50 with step 5. Float may be 0.00000012 and so it is not less or equal than 0.0. You can calculate the float from your cycle variable when needed.
Upvotes: 2