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 _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost