Question

I have got a problem. I got this function in a class "invKin" to set some parameters before I ran a simulation:

void IK_mm4::set_timesetting(double *T_horiz_, double *delta_t_)
{
  T_horiz  = T_horiz_;
  delta_t  = delta_t_;

  k_end = (int)floor((*T_horiz)/(*delta_t));

  cout << "k_end = " << k_end <<endl;
}

It is invoked in my main-file with

...
double delta_t = 5e-3;
double *T_desired = new double(5.0);
...
invKin.set_timesetting(T_desired,&delta_t);
...

The problem is now. At the PC at my university everything is fine and k_end has the value '1000' as it should have. At my home PC the system is somehow giving back the value '999'. If I change the value of *T_desired down to '0.05' cout is giving the right value of '10' at both PCs.

I have already checked to use a variable

double k_end_test = (*T_horiz)/(*delta_t);

that is giving the correct solution of '1000'. The error must be in the floor function or the int-conversion. If I do

int k_end_test2 = (int)(k_end_test);

or

double k_end_test2 = floor(k_end_test);

the result is always '999'.

Does somebody have an idea where this can come from?

I am thankful for any kind of hints! Thank You!

Was it helpful?

Solution

This is the nature of limited-precision representations.

For example, consider six decimal digits of precision. This is not what double uses, of course, but the concept is precisely the same. 1/3 is .333333 with six digits of decimal precision. So 30 * (1/3) is 9.99999. If you round down to an integer, you get 9, not 10. This is the problem you are seeing.

If you don't want this behavior, don't use floating point.

It may suffice to add a small "delta" to the value you pass to floor.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top