Boost logo

Boost :

Subject: Re: [boost] Boost.Math and Math Constants
From: Dave Abrahams (dave_at_[hidden])
Date: 2011-12-17 09:23:04


For what it's worth, I've been doing some experiments with constexpr in
GCC and it's now possible to compute maximally-precise
statically-initialized constants for any floating type via series
expansion, at compile-time. Crazy stuff.

on Fri Dec 16 2011, "Paul A. Bristow" <pbristow-AT-hetp.u-net.com> wrote:

>> -----Original Message-----
>
>> From: boost-bounces_at_[hidden] [mailto:boost-bounces_at_[hidden]] On Behalf Of Barend
>> Gehrels
>> Sent: Thursday, December 08, 2011 7:22 PM
>> To: boost_at_[hidden]
>> Subject: Re: [boost] Boost.Math and Math Constants
>>
>> On 8-12-2011 11:19, John Maddock wrote:
>> >> Nice. But actually I need something else too. I don't think I mailed
>> >> this earlier so I use this announcement to describe this additional
>> >> wish/suggestion shortly.
>> >>
>> >> pi<Real>() is a macro/function, but there should be a structure
>> >> behind. If I want to use a templated user defined type, such as
>> >> ttmath (I'm a fan of that library), I'm stuck (unless I oversee
>> >> something). Because it boost::math::constants::pi<T> cannot be
>> >> partially specialized because it is a function.
>> >
>> > Ah yes, the functions can only be fully specialized, and yes we could
>> > relatively easily add a struct layer in behind the function.
>>
>> That would be perfect!
>
> John has worked more macro magic, so that the effect a that Boost constant macro like
>
> BOOST_DEFINE_MATH_CONSTANT(pi, 3.141592653589793238462643383279502884,
> 1971693993751058209749445923078164062862089986280348253421170679821480865, 0);
>
> for pi now generates a struct so partial specialization is now possible as Barend requested.
>
> The C++ that this produces is show below (and will be in the Boost.Math docs), but we'd just like to
> check that this meets your needs/suggestion.
>
> (An example of using this with ttmath would be nice for the docs? Could provide one?)
>
> Paul
>
> // Preprocessed pi constant, annotated.
>
> namespace boost
> {
> namespace math
> {
> namespace constants
> {
> namespace detail
> {
> template <class T> struct constant_pi
> {
> private:
> // Default implementations from string of decimal digits:
> static inline T get_from_string()
> {
> static const T result
> =
> detail::convert_from_string<T>("3.141592653589793238462643383279502884197169399375105820974944592307
> 81640628620899862803482534211706798214808651e+00",
> boost::is_convertible<const char*, T>());
> return result;
> }
> template <int N> static T compute();
>
> public:
> // Default implementations from string of decimal digits:
> static inline T get(const mpl::int_<construct_from_string>&)
> {
> constant_initializer<T, & constant_pi<T>::get_from_string >::do_nothing();
> return get_from_string();
> }
> // Float, double and long double versions:
> static inline T get(const mpl::int_<construct_from_float>)
> {
> return 3.141592653589793238462643383279502884e+00F;
> }
> static inline T get(const mpl::int_<construct_from_double>&)
> {
> return 3.141592653589793238462643383279502884e+00;
> }
> static inline T get(const mpl::int_<construct_from_long_double>&)
> {
> return 3.141592653589793238462643383279502884e+00L;
> }
> // For very high precision that is nonetheless can be calculated at compile time:
> template <int N> static inline T get(const mpl::int_<N>& n)
> {
> constant_initializer2<T, N, & constant_pi<T>::template compute<N> >::do_nothing();
> return compute<N>();
> }
> //For true arbitrary precision, which may well vary at runtime.
> static inline T get(const mpl::int_<0>&)
> {
> return tools::digits<T>() > max_string_digits ? compute<0>() :
> get(mpl::int_<construct_from_string>());
> }
> }; // template <class T> struct constant_pi
> } // namespace detail
>
> // The actual forwarding function (including policy to control precision).
> template <class T, class Policy> inline T pi( )
> {
> return detail:: constant_pi<T>::get(typename construction_traits<T, Policy>::type());
> }
> // The actual forwarding function (using default policy to control precision).
> template <class T> inline T pi()
> {
> return pi<T, boost::math::policies::policy<> >()
> }
> } // namespace constants
>
> // Namespace specific versions, for the three built-in floats:
> namespace float_constants
> {
> static const float pi = 3.141592653589793238462643383279502884e+00F;
> }
> namespace double_constants
> {
> static const double pi = 3.141592653589793238462643383279502884e+00;
> }
> namespace long_double_constants
> {
> static const long double pi = 3.141592653589793238462643383279502884e+00L;
> }
> namespace constants{;
> } // namespace constants
> } // namespace math
> } // namespace boost
>
> _______________________________________________
> Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
>

-- 
Dave Abrahams
BoostPro Computing
http://www.boostpro.com

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