Boost logo

Boost :

From: Joerg Walter (jhr.walter_at_[hidden])
Date: 2003-01-27 17:07:25


Hi Paul,

you wrote:

> > I've again tried to compile this with GCC 3.2.1. Here are the
diagnostics:
> >
> > In file included from test_circle_area.cpp:12:
> > function_constants.hpp:83: uninitialized const `
> > boost::math::float_constants::pi
> >
> > The following workaround (applied to all constants) heals this
> >
> > namespace float_constants
> > {
> > #ifndef __GNUC__
> > constant< float, pi_tag > const pi;
> > #else
> > constant< float, pi_tag > const pi = constant< float, pi_tag >();
> > #endif
> > }
>
> This may be better for all platforms? I'll think about this.

Some more information: ICC 7.0 seems to accept both forms and Kylix none of
them (didn't analyze further) ;-(

> > The preprocessor symbol __TIMESTAMP__ seems to be platform specific.
> Agreed - but I personally find it useful so tend to use it. I should
bracket
> with #ifdef MSVC ...
> >
> > Ok, back to my earlier question. If I understand you correctly, we
better
> > should write
> >
> > return boost::math::constant< T, boost::math::pi_tag >() * radius *
radius;
> >
> > instead of something like
> >
> > return boost::math::constant< T >::pi() * radius * radius;
> >
> > in generic code? I'll have to think about this.
>
> It depends if Boosters decide to accept this fancy presentation of pi.
>
> If not, then going back to the macro (long double)
>
> #define PI 3.141592653589793238462643383279502884197L
>
> and using the compiler to convert to type T

As far as I understand long double is optional (in IEEE 754). This would
mean you'd have to provide the double constant, too.

> template <typename T>
> T circle_area(const T& radius)
> {
> // Usage example: circle_area<double>( 2.) // Explicit type double.
> // or circle_area(2.F) // Implicit type float.
> return T(PI) * radius * radius;
> }

Interesting option. I'll probably play with it one day.

> *_probably yields_* the same end result
> (as will the appropriate function of float pi(), double pi(), long double
pi()).

When these use the same (long double) constant internally?

> But if you want the exactly representable value for interval arithmetic,
> then I think the form
>
> return boost::math::constant< T, boost::math::pi_tag >() * radius *
radius;
>
> will always give the exact value for pi.
>
> (But, to confuse the matter further, is it not going to be more accurate,
if
> less portable, to calculate PI * radius * radius using long double before
a
> final rounding to type T? So we are choosing portability over accuracy
here,
> rightly in my view. Anyone who wants maximum accuracy will have to do
their own
> thing with the 40 decimal digit macro value for pi, and probably only
wants long
> double type anyway.)

Thanks,

Joerg


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