Boost logo

Boost :

From: Paul A. Bristow (pbristow_at_[hidden])
Date: 2001-04-23 10:08:42


> -----Original Message-----
> From: John Maddock [mailto:John_Maddock_at_[hidden]]
> Sent: Sunday, April 22, 2001 12:02 PM
> To: INTERNET:boost_at_[hidden]
> Subject: [boost] Boost.MathConstants: Review
>
> 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.

Is this double rounding really true?
Isn't the macro simply a textual replacement?
Does it ever give a different result? (Experience suggests that it
doesn't).

Please can any language lawyers pronounce authoritively on this?

>
> 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?

Well spotted!

>
> 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.

Can you explain why please?

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

As Beman suggests I will add this.

>
> 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 don't see how to provide extensibility either,
though adding new constants should be easy, very low risk
of causing trouble, and quite infrequent?

> 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.

I think there are other physical constants which would be useful, but
which are no really constant (and have an uncertainty which should be
included) So I think we should type more to distinguish math from physical
constants.

> 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?

I will study this - I am ashamed to plead ignorance so far.

Paul


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