Boost logo

Boost :

From: John Maddock (John_Maddock_at_[hidden])
Date: 2001-04-22 06:01:33


First let me say that mathematical constants should clearly be part of
boost, and come to that part of a future standard. I'm also impressed that
Paul is generating so many constants to such a high precision.

However I have a few problems with the library as it stands:

I don't like the use of macros here, I would prefer templates as others
have already suggested.

The documentation suggests:

" Const double pi = (double)BOOST_PI; /* C style cast */"

But that involves rounding the constants twice - once to a long double, and
then again to a float/double, potentially that is less precise than using

   const double pi = 3.14159265358979323846264338327950288;
   const float fpi =3.14159265358979323846264338327950288F;

each of which should only be rounded once.

BTW I assume that:

"Or C++ static cast down to double and/or float precisions.

  const long double pi = static_cast<double>(BOOST_PI); // C++ static cast
  const long double piF = static_cast<float>(BOOST_PI); // C++ static cast
"

is a typo - the declared types should be double and float respectively?

One possible implementation strategy to avoid the constants getting rounded
twice would be to use something like:

#define BOOST_PI 3.14159265358979323846264338327950288

#define BOOST_JOIN(x,y) BOOST_DO_JOIN(x,y)
#define BOOST_DO_JOIN(x,y) x##y

namespace boost{

template <class T>struct constants;

template<>
struct constants<float>
{
static float pi() { return BOOST_JOIN(BOOST_PI, F); }
};
template<>
struct constants<double>
{
static double pi() { return BOOST_PI; }
};
template<>
struct constants<long double>
{
static long double pi() { return BOOST_JOIN(BOOST_PI, L); }
};

#undef BOOST_PI

I also agree that to get the constants really correct for a particular
platform one would have to generate the actual binary representation, the
template approach allows for that.

*************************************************************************

Some points I haven't seen mentioned yet:

The docs provide a nice rationale, but don't indicate what constants are
actually available (perhaps the most important point?).

Defining the constants as members of a template, allows us to add
specialisations for types other than built in floating point types - for
example if we add boost::interval or boost::bcd, then these should have
math constants available as well. BTW what ever happened to the boost
interval library?

In an ideal world the interface would also be extensible to allow
additional constants to be added (perhaps by third parties), I don't see
how we can do that though, other than by adding new template classes for
new categories of constants.

I prefer "boost::constants<T>" to the "boost::math::constants<T>" which
some have suggested, I don't see what the latter buys us, other than more
typing. Shouldn't nested namespaces be reserved for things probably not
used by end users (or only used by power users), this definitely in the end
user camp.

How does this library interact with the POSIX standard, see
http://www.opengroup.org/onlinepubs/007908799/xsh/math.h.html for a
listing, these don't cut and paste well :-(

I assume that this library provides a superset of these values?

- John Maddock
http://ourworld.compuserve.com/homepages/john_maddock/


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