0

I am doing a loop to perform some calculations from t=0 to t=1 (included).

That should be easy like this:

for(double t = 0; t<=1; t = t + 0.05)
{
DEBUG_LOG1 (LVL1, t);
//DoMaths
}

But for some reason, t is being logged from 0 to 0.95, not including t=1, as it if was t<1 instead of t<=1.

Where is the problem in my code?

Daniel Viaño
  • 485
  • 1
  • 9
  • 26
  • In addition to the nice answers you got: Calculate the amount of timesteps and use an integer representation for the index of the loop, and calculate `t=i*dt` or `t+=dt`. – Bernhard Oct 27 '17 at 11:32

3 Answers3

4

This is a simple problem with types. Because it is a floating point number will will likely never get precisely 0.05 or 1.00. Rather you'll it will try for 0.05 but really will be something like 0.050000000000000012 which added together 20 times is not 1 but more like 1.00000000000000024 and will therefore not correspond with 1.

There is not problem with your code per se since you catch the problem by using <= instead of =.

You can read more about floating point numbers on http://www.learncpp.com/cpp-tutorial/25-floating-point-numbers/

  • The bottom line is that you should never compare floating point values for equality. The GCC compiler has the "-Wfloat-equal" flag: "Warn if floating-point values are used in equality comparisons." – man.in.the.middle Oct 27 '17 at 11:26
1

I think it may be because 0.05 is not exactly representable as a floating point value. It is only approximate. Try running this program.

#include <stdio.h>

int main()
{
    double x = 0.05;
    printf("%.50lf\n", x);
    return 0;
}

Here I tell printf to give me a lot of excess precision. This prints out the value

0.05000000000000000277555756156289135105907917022705.

Now if I take that value and multiply and add 0.5 to it 19 times in a loop I get...

1.00000000000000022204460492503130808472633361816406

See how it is not exactly 1 but slightly greater. This is the reason comparing equality between floats leads to strange results. You can get around this by adding a small epsilon to 1. For instance compare to 1.001 in your loop.

chasep255
  • 11,745
  • 8
  • 58
  • 115
1

Decimal numbers can't be accurately represented using floating types. For example 0.05 can't be accurately represented in type double and depending on the platform it might be: 0.050000000000000003 or similar. So that tiny little bit always gets added in your loop. By the time you think it is 0.95 it is actually 0.95000000000000029 or similar and adding 0.05 makes it greater than 1, hence the observed results. More info on the subject in this SO post:
Is floating point math broken?

Ron
  • 14,674
  • 4
  • 34
  • 47