Boost logo

Boost :

From: Eric Ford (eford_at_[hidden])
Date: 2001-09-28 02:01:33


> 2) Implementation Issues
>
> C99 (not C89, and hence not ISO-C++) defines the "suffix functions"
> (such as sinf for float arguments, sinl for long double, etc).
These
> are therefore NOT part of the ISO-C++ standard, and I don't think
you
> should be using them as the "implementation" for the template
functions
> for a standards compliant, portable "reference implementation". But
you
> don't need them anyway, I don't think, since the standard overload
> resolution mechanism should allow the compiler to pick the right
> overloaded function. For example, shouldn't these pick the right
> overloads at compile time? (incidentally, shouldn't the special
> functions library, as mentioned before, also be doing this?)
>
> template<> inline float sin<float>(float x) { return ::std::sin(x);
};
> template<> inline double sin<double>(double x) { return
::std::sin(x);
> };
> template<> inline long double sin<long double>(long double x) {
return
> ::std::sin(x); };
>
> Is there something that I am missing here? Is there a good reason
not
> to do this and to rely on non-standard functions?

You may be right about what the standards specify. However with g++
2.95, it looks like there is no overloading for float sin(float x) or
long double sin(long double x). For example when I do...

#include<cmath>
#include<iostream>
int main(int, char * [] )
{
   cout.precision(19);
   float xf = 2.f;
   double xd = 2.;
   long double xl = 2.L;

  cout << " xf = " << xf ;
  cout << " xd = " << xd ;
  cout << " xl = " << xl << endl;
  cout << "std::sqrt(xf) = " << std::sqrt(xf) << endl;
  cout << "std::sqrt(xd) = " << std::sqrt(xd) << endl;
  cout << "std::sqrt(xl) = " << std::sqrt(xl) << endl;
  cout << "std::sqrtf(xf) = " << std::sqrtf(xf) << endl;
  cout << "std::sqrt(xd) = " << std::sqrt(xd) << endl;
  cout << "std::sqrtl(xl) = " << std::sqrtl(xl) << endl;
  return 0;
}

I get...
 xf = 2 xd = 2 xl = 2
std::sqrt(xf) = 1.414213562373095145
std::sqrt(xd) = 1.414213562373095145
std::sqrt(xl) = 1.414213562373095145
std::sqrtf(xf) = 1.41421353816986084
std::sqrt(xd) = 1.414213562373095145
std::sqrtl(xl) = 1.414213562373095049

Are you sure the C++ standard is to overload these functions for types
other than double? Cause it doesn't look like that's happening for my
g++. Of course, if C++ doesn't define sqrtf and sqrtl, then my
original code still isn't portable. As for solutions, casting a float
to a double, calling sqrt, and casting the result back to a float
isn't so bad. That's unacceptable for long doubles, so maybe those
are left undefined? Not so pretty. I suppose some preprocessor flags
could allow it to use the *f and *l functions if they were avaliable,
but that's not very elegant.

E


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