Boost logo

Boost :

From: rogeeff (rogeeff_at_[hidden])
Date: 2001-12-06 15:55:30


--- In boost_at_y..., Dave Gomboc <dave_at_c...> wrote:
> > What I suggest is to provide something like:
> >
> > template<class T> bool fp_equal(T const& l,T const& r) ;
> > template<class T> bool fp_equal2(T const& l,T const& r, T const&
tol)
> ;
> > template<class T> bool fp_equal32(T const& l,T const& r, T const&
tol)
> ;
>
> Using a fixed epsilon is bogus for the numerical applications that
I am
> familiar with. What we really need to do is make the third
argument a
> binary predicate returning bool whose operator() is called with the
> first two arguments. That wasn't a great explanation, but I hope
you
> get what I mean.
>
> Dave Gomboc

What algorithm you proposing? Or al least examples?

In simple case fixed epsilon could work. In more complex cases having
final compared values may not be enouph either. For example try to
compile using your compiler following program:

#include <iostream>
#include <typeinfo>
#include <limits>

template<class T>
void foo( T shift )
{
    T v = static_cast<T>( 1.0001 );
    v += static_cast<T>( shift );
    v -= static_cast<T>( shift );

    T diff = v - static_cast<T>( 1.0001 );

    std::cout << typeid(T).name() << std::endl;
    std::cout << diff << std::endl;
    std::cout << diff / std::numeric_limits<T>::epsilon() <<
std::endl;
}

int main() {
    float v1;
    double v2;
    long double v3;

    v1 = 1.e-5;
    v2 = 1.e-5;
    v3 = 1.e-5;

    foo( v1 );
    foo( v2 );
    foo( v3 );

    std::cout
<< "********************************************************" <<
std::endl;
    
    v1 = 1.e+5;
    v2 = 1.e+5;
    v3 = 1.e+5;

    foo( v1 );
    foo( v2 );
    foo( v3 );

    std::cout
<< "********************************************************" <<
std::endl;

    v1 = 1.e+10;
    v2 = 1.e+10;
    v3 = 1.e+10;

    foo( v1 );
    foo( v2 );
    foo( v3 );

    return 0;
}

//******************************************************************//
//******************************************************************//

MSVC results with STLPort:

float
0
0
double
0
0
long double
0
0
********************************************************
float
0
0
double
4.74976e-12
21391
long double
4.74976e-12
21391
********************************************************
float
-8.34465e-07
-7
double
-8.17871e-07
-3.68336e+09
long double
-8.17871e-07
-3.68336e+09

//******************************************************************//

SunPro Forte C++ u.2

float
0
0
double
0
0
long double
0
0
********************************************************
float
-0.000100017
-839
double
4.74976e-12
21391
long double
0
0
********************************************************
float
-1.0001
-8.38945e+06
double
-8.17871e-07
-3.68336e+09
long double
0
0

//******************************************************************//

gcc 2.91 on Linux
f = float, d - double, r - long double
does not have a numeric_limits

f
0
d
0
r
0

********************************************************
f
-0.000100017
d
4.74976e-12
r
3.33067e-15
********************************************************
f
-1.0001
d
-8.17871e-07
r
-1.69873e-10

As you can see my algorithm won't work here. Yours?

Gennadiy.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk