[boost] RE: math constant - generic function circle_area example.
by Paul A. Bristow other posts by this author
Jan 23 2003 12:24AM messages near this date
math constant formal review request (was: [boost] Interval library
merge)
|
Re: [boost] RE: math constant - generic function circle_area example.
> [snip]
>
> 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;
}
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?
Paul
Paul A Bristow, Prizet Farmhouse, Kendal, Cumbria, LA8 8AB UK
+44 1539 561830 Mobile +44 7714 33 02 04
Mobile mailto:pabristow@[...].uk
mailto:pbristow@hetp.u-net.com
Attachments:
function_constants.hpp
Generic_function.vcproj
test_circle_area.cpp
unknown4
Thread:
Joerg Walter
Paul A. Bristow
Joerg Walter
Paul A. Bristow
Paul A. Bristow
Joerg Walter
Paul A. Bristow
Joerg Walter
Paul A. Bristow
|