-1

I am writing a c++ function to locate a given double from a matrix (ie return the indices, as (i,j)). this is the function i have written :

std::pair<int,int> locate(std::vector<std::vector<double> >&t, double d) {
 std::pair<int,int> p = make_pair(0,0); // initialising
 cout<<"double given : "<<d<<"\n";
 for (int i = 0; i < t.size(); ++i)
 {
    for (int j = 0; j < t[i].size(); ++j)
    {
        if (d==t[i][j])
        {
            p = make_pair(i,j);
            cout<<"YES";
            return p;
        }
        else {
            cout<<"NO ";
            continue;
        }
    }
    cout<<"\n";
 }
}

the given matrix is

50400.5 43220.8 46053.4 46700.8 44800.8  
50460.5 43160.8 46293.4 46640.8 44540.8  
50620.5 43220.8 45833.4 46720.8 44480.8

and the output i get is

double given : 43220.8
NO NO NO NO NO 
NO NO NO NO NO 
NO NO NO NO NO 
43220.8 : 0,0

i am invoking it as

std::pair<int,int> p;
double d = 43220.8;
p = locate(raw_1_set_man,d); // raw_1_set_man is the matrix
cout<<"43220.8 : "<<p.first<<","<<p.second<<"\n";

Control is not entering the if block
where did i do wrong?

klbm9999
  • 31
  • 9
  • 5
    You can't compare floating point values with equals. Read this: http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm – Leandros Apr 20 '16 at 13:27
  • [here](http://stackoverflow.com/questions/17333/most-effective-way-for-float-and-double-comparison) [here](http://stackoverflow.com/questions/10334688/how-dangerous-is-it-to-compare-floating-point-values) and [here](http://stackoverflow.com/questions/4548004/how-to-correctly-and-standardly-compare-floats) – gongzhitaao Apr 20 '16 at 13:30
  • Got it. Thank, thank you for your help – klbm9999 Apr 20 '16 at 13:47

1 Answers1

1

Compare using epsilon:

bool doubleEqual(double d1, double d2, double epsilon = std::numeric_limits<T>::epsilon())
{
    return d1 <= d2 + epsilon && d1 + epsilon >= d2;
}

or some epsilon that is better fitting for your purpose. Please be cautious with this method, though, and also consider the comments to this answer and the comments to the question.

IceFire
  • 3,719
  • 2
  • 19
  • 46
  • How to pick a suitable epsilon please? – Maxim Egorushkin Apr 20 '16 at 13:31
  • I have made an edit, std::numeric_limits offers an epsilon. Also, whoever downvotes could please give a reason – IceFire Apr 20 '16 at 13:32
  • 1
    Even comparison with `numeric_limits` is wrong. Read [this](http://stackoverflow.com/questions/17333/most-effective-way-for-float-and-double-comparison) and [this](http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm). – Leandros Apr 20 '16 at 13:33
  • The sources state that you have to be careful, not that it is wrong in itself. What you seem to mean is: Be careful when using those solutions because - depending on context - they might lead to wrong results – IceFire Apr 20 '16 at 13:35
  • 1
    Disclaimer: I didn't downvote. 1) OP's values are **far** from 1.0. So using epsilon is asking for trouble. What could be used, but the OP must check the use case, are: [std::nextafter](http://en.cppreference.com/w/cpp/numeric/math/nextafter) and std::nexttoward – fjardon Apr 20 '16 at 13:37
  • 1
    Well, yes, of course, that's correct. Sometimes you even want `flt1 == flt2`, but in most times you don't want that. And it's most likely not the case here. The `numeric_limits` is the minimum value between two representable floats between 0 and 1 on the current machine. OP wants a comparison using ULP. – Leandros Apr 20 '16 at 13:38
  • comparison with `numeric_limits` is not working, a suitable epsilon chosen by me is working and is fine by me. Thanks for the help everyone. – klbm9999 Apr 20 '16 at 13:46
  • yes, depending on the purpose a larger epsilon might work, that is highly case-dependant. Thanks also for Leandros' and fjardon's valuable comments – IceFire Apr 20 '16 at 13:47