|
Boost : |
From: Joerg Walter (jhr.walter_at_[hidden])
Date: 2003-01-23 19:27:05
Hi Paul,
you wrote:
> > I've been looking into an earlier version of the proposed math constants
> > before and asked myself how to implement a generic function like
> >
> > template<class T>
> > T circle_area (const T &radius) {
> > return math_constants<T>::pi * radius * radius;
> > }
> >
> > How should this be done?
> >
> > Thanks,
> >
> > Joerg
>
> Attached is an example using Michael Kenniston's Kunning Function
constants.
>
> Briefly
>
> 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 boost::math::constant< T, boost::math::pi_tag >() * radius *
radius;
> }
OK. I've tried to compile this with GCC 3.2.1 and after applying some
remedies like
<for example>
#ifdef LATER
// Define constant is namespaces to hold three builtin floating-point
representations.
namespace float_constants
{
constant< float, pi_tag > const pi;
}
namespace double_constants
{
constant< double, pi_tag > const pi;
}
namespace long_double_constants
{
constant< long double, pi_tag > const pi;
}
#endif
</for example>
it compiled and executed giving the expected results. How is this solution
related to your latest (Dec. 12) upload at groups.yahoo.com/group/boost?
> It compiles with MSVC 7.0 (but not 6 - see MK's original example for why
not).
> (long double == double for MSVC, so long double not fully
testable/useful).
>
> It seems to do the trick, without too many surprises. I have displayed
the
> output using the 17 significant digits for double so one can see the
difference
> between a float pi 3.1415927410125732 and a double pi 3.1415926535897931
(even
> though only 9 are really significant for float).
>
> cout << "circle_area<float>(1.) = " << circle_area<float>(1.) << endl; //
> Explicit type float.
> cout << "circle_area<double>(1.) = " << circle_area<double>(1.) << endl;
//
> Explicit type double.
> cout << "circle_area(1.F) = " << circle_area(1.F) << endl; // Implicit
type
> float.
> cout << "circle_area(1.) = " << circle_area(1.) << endl; // Implicit type
> double.
> cout << "circle_area(1.L) = " << circle_area(1.L) << endl; // implicit
type
> long double.
> cout << "circle_area<double>(1.F) = " << circle_area<double>(1.F) <<
endl; //
> Explicit over-rides implicit.
>
> And silly types like int fail helpfully.
> // cout << "circle_area(1) = " << circle_area(1)<< endl; // Implicit
int -
> does not link!
> // cout << "circle_area<int>(1.) = " << circle_area<int>(1.)<< endl; //
> Explicit int - does not compile!
>
> Output is
>
> Test test_circle_area.cpp Thu Jan 23 00:06:28 2003
> float pi = 3.14159274
> double pi = 3.1415926535897931
> float pi = 3.1415927410125732
> circle_area<float>(1.) = 3.1415927410125732
> circle_area<double>(1.) = 3.1415926535897931
> circle_area(1.F) = 3.1415927410125732
> circle_area(1.) = 3.1415926535897931
> circle_area(1.L) = 3.1415926535897931
> circle_area<double>(1.F) = 3.1415926535897931
> circle_area<long double>(1.) = 3.1415926535897931
> circle_area<float>(2.) = 12.566370964050293
> circle_area<double>(2.) = 12.566370614359172
> circle_area(2.F) = 12.566370964050293
> circle_area(2.) = 12.566370614359172
> circle_area(2.L) = 12.566370614359172
> circle_area<double>(2.F) = 12.566370614359172
> boost::math::constant< float, boost::math::pi_tag >() 3.1415927410125732
>
> I haven't looked at any assembler to check on efficiency, but believe/hope
from
> previous examples that it will be optimal if inlined.
>
> Does this look sensible/useful?
Only if I learn to see the relation to your latest upload (which I'm
assuming your review request is related to).
Best,
Joerg
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk