0

I am running the following block of code inside a CALLBACK function for a timer.

if (start_value <= end_value) 
{
   start_value += increment_value;
}
else
{
   return 0;
}

all three variables are defined as DOUBLE.

Double start_value = 26.0;
Double end_value = 28.0;
increment_value = 0.1;

when adding the increment_value to start_value, the value of the variable start_value does not simply reflect the expected result of the addition. For example, when start_value is 26.0, after one addition, the value of start_value is 26.10000000001. The trailing 1 causes problems later on in the code, because when the expected result of the comparison is expected to be TRUE, it is evaluated as false because of the trailing 1. Why is this happening?

ryyker
  • 22,849
  • 3
  • 43
  • 87
Essi Shams
  • 159
  • 1
  • 13
  • 1
    Eshan, It seems I completely missed the real issue in your question with my sollution. This was brought to my attention, thanks to @Pascal's observations. My aplogies. My solution is misleading, and I will either edit it, or delete it depending on whether you have already resolved your issue. So, 2 questions: Can you confirm then that the _real issue_ here is that when 0.1 is added to 26.0, 26.10000000001 stored in memory instead of 26.1. correct? And is this still a concern for you? – ryyker Oct 09 '13 at 17:33
  • @ryykey, I think your answer is appropriate. My question, whether I was able to write it well or not, was why I was ending up with 26.10000001 instead of 26.1 (which you neatly explained by referring to floating-point error). You also explained that a different comparison needs to be used. Now whether or not I use your suggested method of comparison is beside the question. Thanks – Essi Shams Oct 09 '13 at 18:05

1 Answers1

0

Eshan, The == operator is looking for an exact match, and should be used exclusively for integer comparisons (where exact is possible). So, "why is this happening?" because 26.10000000001 is not equal to 26.1. The difference between the two is sometimes referred to as floating point error.

As long as we are using binary storage of floating point, there will continue to be floating point error. This requires that methods to compare floating points have to be different than when comparing integers. (i.e. for floats, cannot use (x == y) ?. A quick and dirty alternative to "==" when comparing floats is to do something like this: if(abs(x-y)<epsilon ){//equal} where epsilon is some small tolerance value like 0.000001

So, try something like this instead:

int main(void)
{
    double start_value = 26.0;
    double end_value = 28.0;
    double increment_value = 0.1;

    #define EPSILON 0.000001  

    while(fabs(start_value-end_value)>EPSILON )
    {
          printf("not equal\n");
          start_value += increment_value;
    }
    printf("equal\n");
    getchar();  
}

Note: choose epsilon value to match the neighborhood of significant digits in the comparisons you will do.

There are many other good methods, (and many who will say this is not one of them) but I have used this one for years, and for my purposes, it has worked well.
HERE is a link talking a little about this, and other methods.

ryyker
  • 22,849
  • 3
  • 43
  • 87
  • What has the fact that 26.10000000001 is not equal to 26.1 got to do with the perceived issue here? – Pascal Cuoq Oct 09 '13 at 00:24
  • The question's program contains the test `start_value <= end_value`. You are basically suggesting to replace a rather sane computation (that admittedly can still be perceived by a programmer unfamiliar with binary arithmetic as giving unexpected results) with a bogus near-equality comparison that relies on an epsilon that you did not indicate how to determine. Following your advice actually makes the code worse. – Pascal Cuoq Oct 09 '13 at 00:33
  • @PascalCuoq - _What has the fact that 26.10000000001 is not equal to 26.1 got to do with the perceived issue here?_ The asker's ONLY real question here is _Why is this happening?_. In the context of of using the `==` operator to compare floats, it is important to start off showing that floats are stored differently than int, long, et.al. and therefore cannot be compared the same way. (i.e. using ==). – ryyker Oct 09 '13 at 17:00
  • The OP is not using `==`. – Pascal Cuoq Oct 09 '13 at 17:04
  • @PascalCuoq - Well - You are correct. I made the assumption (perhaps wrongly) that asker's statement (_later on in the code, because when the expected result of the comparison_) meant that he was at some point using `==`. As I re-read it in the context of your comment, that is probably not the case, and conversely, my solution is not addressing the real issue. Thank you. – ryyker Oct 09 '13 at 17:25