-2

I am having trouble with an if statement that doesn't always return true when it meets the condition (see code below).

This if statement is in a loop that is embedded in another loop that runs for 7 (6, actually because the last one is empty) iterations and I have noticed that it works correctly for the first 3 iterations. The thing that drew my attention was that

  • in the first iteration of loop 1 the condition is met at the 3rd iteration of loop 2 and it returns true
  • in the second iteration of loop 1 the condition is met at the 2nd iteration of loop 2 and it returns true
  • in the third iteration of loop 2 the condition is met at the 1st iteration of loop 2 and it returns true
  • in the 4th iteration the condition is true in all cases, but it always returns false
  • in the 5th iteration the condition is false in all cases and it returns false
  • same in the 6th iteration
  • the 7 iteration of the loop is empty

void compute_neighbours(vector<vector<double>> &positions,double &GPmin, double &GPmax)
{
 vector<int> neighbours_i;
 neighbours.assign(positions.size(),neighbours_i);

 for (unsigned i=0; i<positions.size();i++)
   {
     cout << "Grid point " << i << " looking at :" << endl;
     for (unsigned k=i+1; k<positions.size();k++)
     {
      cout << " " << k << " distance: ";
      double r=delta(positions[k],positions[i]).modulo();
      cout << r << ", GPmin: " << GPmin << ", GPmax: " << GPmax;
      if ((r>=GPmin) and (r<=GPmax))
      {
        cout << "--adding point ";
        neighbours[i].push_back(k);
        neighbours[k].push_back(i);
      }

      cout << endl;
     }
   }
}

This is the output I obtain:

Grid point 0 looking at :
 1 distance: 0.212132, GPmin: 0, GPmax: 0.15
 2 distance: 0.212132, GPmin: 0, GPmax: 0.15
 3 distance: 0.15, GPmin: 0, GPmax: 0.15--adding point 
 4 distance: 0.212132, GPmin: 0, GPmax: 0.15
 5 distance: 0.212132, GPmin: 0, GPmax: 0.15
 6 distance: 0.3, GPmin: 0, GPmax: 0.15
Grid point 1 looking at :
 2 distance: 0.212132, GPmin: 0, GPmax: 0.15
 3 distance: 0.15, GPmin: 0, GPmax: 0.15--adding point 
 4 distance: 0.212132, GPmin: 0, GPmax: 0.15
 5 distance: 0.3, GPmin: 0, GPmax: 0.15
 6 distance: 0.212132, GPmin: 0, GPmax: 0.15
Grid point 2 looking at :
 3 distance: 0.15, GPmin: 0, GPmax: 0.15--adding point 
 4 distance: 0.3, GPmin: 0, GPmax: 0.15
 5 distance: 0.212132, GPmin: 0, GPmax: 0.15
 6 distance: 0.212132, GPmin: 0, GPmax: 0.15
Grid point 3 looking at :
 4 distance: 0.15, GPmin: 0, GPmax: 0.15
 5 distance: 0.15, GPmin: 0, GPmax: 0.15
 6 distance: 0.15, GPmin: 0, GPmax: 0.15
Grid point 4 looking at :
 5 distance: 0.212132, GPmin: 0, GPmax: 0.15
 6 distance: 0.212132, GPmin: 0, GPmax: 0.15
Grid point 5 looking at :
 6 distance: 0.212132, GPmin: 0, GPmax: 0.15
Grid point 6 looking at :
Grid Point 0's neighbours are: 3,
Grid Point 1's neighbours are: 3,
Grid Point 2's neighbours are: 3,
Grid Point 3's neighbours are: 0,1,2,
Grid Point 4's neighbours are: 
Grid Point 5's neighbours are: 
Grid Point 6's neighbours are: 
Maximum number of neighbours: 3

Grid point 3 should also be neighbours with 4, 5 and 6, but for some reason the if statement returns false even if the distance falls into the specified range (which doesn't happen in the other iterations of the loop).

I have tried replacing the delta().modulo() function by a manually coded euclidean distance, and obtained the same results.

Any ideas about what is going wrong will be greatly appreciated!

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
user3091644
  • 419
  • 5
  • 7

1 Answers1

4

You are running into a round off error. It prints 0.15, but in reality is something slightly smaller or larger, so that the comparison fails.

For example,

#include <iostream>

int main() {
  double x = 0.15, y = 0.14999999999;
  if (x <= y)
    std::cout << "Equation returns true." << std::endl;
  else
    std::cout << "x = " << x << "; y = " << y << "; but x <= y is false." << std::endl;
}

which prints

x = 0.15; y = 0.15; but x <= y is false.

See https://ideone.com/GoRkqD

Carlo Wood
  • 5,648
  • 2
  • 35
  • 47