user1037: I have a timer interrupt that controls a stepper motor, on an UNO board. In the interrupt handler it checks the speed of the motor and compares it to the target speed. This allows the motor to accelerate to the target speed in a non-blocking way.
This is the relevant part of the interrupt handler:
ISR(TIMER1_COMPA_vect){
    if (targetSpeed > 0 || motorSpeed > 0){
        // leading edge of the step cycle
        if (leadingEdge){
            digitalWrite(STEP_PIN, HIGH);
            stepNumber++;
            // check speed and adjust if necesary
            if (motorSpeed < targetSpeed){
                motorSpeed += speedIncrement;
            }
            else if (motorSpeed > targetSpeed){
                motorSpeed -= speedIncrement;
            }

            leadingEdge = false;
        }
        // trailing edge
        else{
            digitalWrite(STEP_PIN, LOW);
            leadingEdge = true;
        }
    }
    OCR1A = minInteruptsPerStep + (minInteruptsPerStep * (1 - motorSpeed));
}

In the loop() I have a function that checks the state of motorSpeed to control other functions
if (motorSpeed == targetSpeed) {
    motorState = RUNNING;
} else if (motorSpeed < targetSpeed) {
    motorState  = ACCELERATING;
} else if (motorSpeed > targetSpeed) {
    motorState  = DECELERATING;
}

motorSpeed and targetSpeed are floats and range from 0-1, in steps of 0.1 speedIncrement is 0.001 As far I can see that should ramp the speed up until motorSpeed == targetSpeed, in 100 steps. And this mostly what happens. The speed gets to targetSpeed and motorState switches from ACCELERATING to RUNNING, as expected.. mostly. The problem is that it occasionally starts flipping between the three states, for no reason I can see--there is nothing that should modify the value of motorSpeed outside the interrupt handler, so once it stops accelerating it should be stable.
Is this because I'm using and comparing floats? Should I scale the speed variables up and use an int or even a byte?

user31105: You should never compare two floats with == or != directly. The reason is that floats are not accurate, so maybe 1.0 can be 0.99999999999, and the other value 1.0 might be 1.00000000001 (simplification). 
Instead, use a 'range', like:
if (fabs(motorSpeed - targetSpeed) < 0.001)
{
   // Equal
}

This means the difference should be smaller than 0.001. fabs means the absolute value of a float (mathematic symbol |x| for the absolute value).
If you make more compares this way, make 0.001 a #define or const.

user4143: The biggest problem here is that floats don't compare well.  The issue is that a float isn't an exact number. It is, to a large extent, an approximation.
Some numbers cannot be represented by floats, so your "100" may be actually "100.00001", or "99.999999".
It is better to use integers whenever possible. Do your calculations using larger numbers, and then scale down the results when you need to use them.
If you're working in steps of 0.1 between 0 and 100, you should really be working instead in steps of 1 between 0 and 1000, and then divide by 10 later on when you need to use the value (if you even really need to do that).
Here's a little example I knocked up on Linux:
#include <stdio.h>

void main() {
    float f = 0;
    while (f < 100) {
        f += 0.1;
    }
    printf("%.6f\n",f);
}

You'd expect it to give "100.000000" as the answer. It doesn't. Instead you end up with 100.099045. That's because the closest it gets to 100 is actually the previous iteration: 99.999046.
If you do want to compare floats the best way is to use a "within X" operation.  Here's a little macro:
#define WITHIN(A,B,DIFF) (fabs((A) - (B)) <= (DIFF))

Then you can:
if (WITHIN(motorSpeed, targetSpeed, 0.1)) { 
    ...
}

That should give you TRUE if the motorSpeed and targetSpeed are within 0.1 of each other.

user7508: You already know, from previous answers, why the comparison doesn't give
you the result you expect: you assumed that any multiple of 0.1 is also
a multiple of 0.001, which is true for real numbers but nor for floats.
To fix the issue, it has been suggested to you to allow for some
fussiness in the comparison. I would suggest a different approach: keep
your comparisons as they are, and instead change the way the speed is
updated in the ISR:
if (motorSpeed < targetSpeed) {
    motorSpeed = min(motorSpeed + speedIncrement, targetSpeed);
}
else if (motorSpeed > targetSpeed) {
    motorSpeed = max(motorSpeed - speedIncrement, targetSpeed);
}

With this logic, motorSpeed will always end up being exactly equal
to targetSpeed, irrespective of whether the speed change is a multiple
of the increment or not.
A common misconception about floating point numbers has it that they are
not exact. Truth is, most floating point calculations involve rounding
errors, but the floating point numbers themselves are exact numbers,
if not the numbers you expect¹. Then, when you do the assignment
motorSpeed = targetSpeed;

which the code above ends up doing at some point, you can test
if (motorSpeed == targetSpeed) ...

and it will be true.
¹ When you write “0.1” in the source code, you get the float which is
closest to 0.1, which happens to be 0.100000001490116119384765625
exactly.

1037: <p>I have a timer interrupt that controls a stepper motor, on an UNO board. In the interrupt handler it checks the speed of the motor and compares it to the target speed. This allows the motor to accelerate to the target speed in a non-blocking way.</p>

<p>This is the relevant part of the interrupt handler:</p>

<pre class="lang-cpp prettyprint-override"><code>ISR(TIMER1_COMPA_vect){
    if (targetSpeed &gt; 0 || motorSpeed &gt; 0){
        // leading edge of the step cycle
        if (leadingEdge){
            digitalWrite(STEP_PIN, HIGH);
            stepNumber++;
            // check speed and adjust if necesary
            if (motorSpeed &lt; targetSpeed){
                motorSpeed += speedIncrement;
            }
            else if (motorSpeed &gt; targetSpeed){
                motorSpeed -= speedIncrement;
            }

            leadingEdge = false;
        }
        // trailing edge
        else{
            digitalWrite(STEP_PIN, LOW);
            leadingEdge = true;
        }
    }
    OCR1A = minInteruptsPerStep + (minInteruptsPerStep * (1 - motorSpeed));
}
</code></pre>

<p>In the <code>loop()</code> I have a function that checks the state of <code>motorSpeed</code> to control other functions</p>

<pre class="lang-cpp prettyprint-override"><code>if (motorSpeed == targetSpeed) {
    motorState = RUNNING;
} else if (motorSpeed &lt; targetSpeed) {
    motorState  = ACCELERATING;
} else if (motorSpeed &gt; targetSpeed) {
    motorState  = DECELERATING;
}
</code></pre>

<p><code>motorSpeed</code> and <code>targetSpeed</code> are floats and range from 0-1, in steps of 0.1 <code>speedIncrement</code> is 0.001 As far I can see that should ramp the speed up until <code>motorSpeed == targetSpeed</code>, in 100 steps. And this mostly what happens. The speed gets to <code>targetSpeed</code> and motorState switches from <code>ACCELERATING</code> to <code>RUNNING</code>, as expected.. mostly. The problem is that it occasionally starts flipping between the three states, for no reason I can see--there is nothing that should modify the value of <code>motorSpeed</code> outside the interrupt handler, so once it stops accelerating it should be stable.</p>

<p>Is this because I'm using and comparing floats? Should I scale the speed variables up and use an int or even a byte?</p>
 31105: <p>You should never compare two floats with == or != directly. The reason is that floats are not accurate, so maybe 1.0 can be 0.99999999999, and the other value 1.0 might be 1.00000000001 (simplification). </p>

<p>Instead, use a 'range', like:</p>

<pre><code>if (fabs(motorSpeed - targetSpeed) &lt; 0.001)
{
   // Equal
}
</code></pre>

<p>This means the difference should be smaller than 0.001. fabs means the absolute value of a float (mathematic symbol |x| for the absolute value).</p>

<p>If you make more compares this way, make 0.001 a #define or const.</p>
 4143: <p>The biggest problem here is that floats don't compare well.  The issue is that a float isn't an exact number. It is, to a large extent, an approximation.</p>

<p>Some numbers cannot be represented by floats, so your "100" may be actually "100.00001", or "99.999999".</p>

<p>It is better to use integers whenever possible. Do your calculations using larger numbers, and then scale down the results when you need to use them.</p>

<p>If you're working in steps of 0.1 between 0 and 100, you should really be working instead in steps of 1 between 0 and 1000, and then divide by 10 later on when you need to use the value (if you even really need to do that).</p>

<p>Here's a little example I knocked up on Linux:</p>

<pre><code>#include &lt;stdio.h&gt;

void main() {
    float f = 0;
    while (f &lt; 100) {
        f += 0.1;
    }
    printf("%.6f\n",f);
}
</code></pre>

<p>You'd expect it to give "100.000000" as the answer. It doesn't. Instead you end up with 100.099045. That's because the closest it gets to 100 is actually the previous iteration: 99.999046.</p>

<p>If you do want to compare floats the best way is to use a "within X" operation.  Here's a little macro:</p>

<pre><code>#define WITHIN(A,B,DIFF) (fabs((A) - (B)) &lt;= (DIFF))
</code></pre>

<p>Then you can:</p>

<pre><code>if (WITHIN(motorSpeed, targetSpeed, 0.1)) { 
    ...
}
</code></pre>

<p>That should give you TRUE if the motorSpeed and targetSpeed are within 0.1 of each other.</p>
 7508: <p>You already know, from previous answers, why the comparison doesn't give
you the result you expect: you assumed that any multiple of 0.1 is also
a multiple of 0.001, which is true for real numbers but nor for floats.</p>

<p>To fix the issue, it has been suggested to you to allow for some
fussiness in the comparison. I would suggest a different approach: keep
your comparisons as they are, and instead change the way the speed is
updated in the ISR:</p>



<pre class="lang-c++ prettyprint-override"><code>if (motorSpeed &lt; targetSpeed) {
    motorSpeed = min(motorSpeed + speedIncrement, targetSpeed);
}
else if (motorSpeed &gt; targetSpeed) {
    motorSpeed = max(motorSpeed - speedIncrement, targetSpeed);
}
</code></pre>

<p>With this logic, <code>motorSpeed</code> will always end up being <em>exactly</em> equal
to <code>targetSpeed</code>, irrespective of whether the speed change is a multiple
of the increment or not.</p>

<p>A common misconception about floating point numbers has it that they are
not exact. Truth is, most floating point calculations involve rounding
errors, but the floating point numbers themselves are <em>exact numbers</em>,
if not the numbers you expect¹. Then, when you do the assignment</p>

<pre class="lang-c++ prettyprint-override"><code>motorSpeed = targetSpeed;
</code></pre>

<p>which the code above ends up doing at some point, you can test</p>

<pre class="lang-c++ prettyprint-override"><code>if (motorSpeed == targetSpeed) ...
</code></pre>

<p>and it will be true.</p>

<p>¹ When you write “0.1” in the source code, you get the <code>float</code> which is
closest to 0.1, which happens to be 0.100000001490116119384765625
<em>exactly</em>.</p>
