$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r75588 - in sandbox/math_constants: boost/math/constants libs/math/test
From: john_at_[hidden]
Date: 2011-11-21 06:42:20
Author: johnmaddock
Date: 2011-11-21 06:42:15 EST (Mon, 21 Nov 2011)
New Revision: 75588
URL: http://svn.boost.org/trac/boost/changeset/75588
Log:
Add tentative cpp_float support.
Add Euler-Gamma calculation.
Update constant values.
Change constant initialization to be lock free.
Added:
   sandbox/math_constants/libs/math/test/cpp_float_test.cpp   (contents, props changed)
Text files modified: 
   sandbox/math_constants/boost/math/constants/calculate_constants.hpp |    88 ++++++++++++++++++++++++++++-           
   sandbox/math_constants/boost/math/constants/constants.hpp           |   120 ++++++++++++++++++++++++++++++----------
   sandbox/math_constants/boost/math/constants/generate.hpp            |     8 ++                                      
   sandbox/math_constants/boost/math/constants/info.hpp                |     4 +                                       
   sandbox/math_constants/libs/math/test/test_constant_generate.cpp    |    20 ++++++                                  
   sandbox/math_constants/libs/math/test/test_constants.cpp            |    12 +++-                                    
   sandbox/math_constants/libs/math/test/test_print_info_on_type.cpp   |     2                                         
   7 files changed, 217 insertions(+), 37 deletions(-)
Modified: sandbox/math_constants/boost/math/constants/calculate_constants.hpp
==============================================================================
--- sandbox/math_constants/boost/math/constants/calculate_constants.hpp	(original)
+++ sandbox/math_constants/boost/math/constants/calculate_constants.hpp	2011-11-21 06:42:15 EST (Mon, 21 Nov 2011)
@@ -12,7 +12,54 @@
 inline T calculate_pi(const mpl::int_<N>&BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))
 {
    BOOST_MATH_STD_USING
-   return 2 * acos(static_cast<T>(0));
+
+   return ldexp(acos(T(0)), 1);
+
+   /*
+   // Although this code works well, it's usually more accurate to just call acos
+   // and access the numner types own representation of PI which is usually calculated
+   // at slightly higher precision...
+
+   T result;
+   T a = 1;
+   T b;
+   T A(a);
+   T B = 0.5f;
+   T D = 0.25f;
+
+   T lim;
+   lim = boost::math::tools::epsilon<T>();
+
+   unsigned k = 1;
+
+   do
+   {
+      result = A + B;
+      result = ldexp(result, -2);
+      b = sqrt(B);
+      a += b;
+      a = ldexp(a, -1);
+      A = a * a;
+      B = A - result;
+      B = ldexp(B, 1);
+      result = A - B;
+      bool neg = boost::math::sign(result) < 0;
+      if(neg)
+         result = -result;
+      if(result <= lim)
+         break;
+      if(neg)
+         result = -result;
+      result = ldexp(result, k - 1);
+      D -= result;
+      ++k;
+      lim = ldexp(lim, 1);
+   }
+   while(true);
+
+   result = B / D;
+   return result;
+   */
 }
 
 template <class T, int N> 
@@ -58,6 +105,11 @@
 template <class T, int N> 
 inline T calculate_e(const mpl::int_<N>&BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))
 {
+   //
+   // Although we can clearly calculate this from first principles, this hooks into
+   // T's own notion of e, which hopefully will more accurate than one calculated to
+   // a few epsilon:
+   //
    BOOST_MATH_STD_USING
    return exp(static_cast<T>(1));
 }
@@ -71,8 +123,33 @@
 template <class T, int N> 
 inline T calculate_euler(const mpl::int_<N>&BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))
 {
-   throw std::runtime_error("A true arbitrary precision Euler's constant is not available - it's too expensive to calculate on the fly - this constant is only supported up to 100 decimal digits.");
-   return 0;
+   //
+   // This is the method described in:
+   // "Some New Algorithms for High-Precision Computation of Euler's Constant"
+   // Richard P Brent and Edwin M McMillan.
+   // Mathematics of Comnputation, Volume 34, Number 149, Jan 1980, pages 305-312.
+   // See equation 17 with p = 2.
+   //
+   T n = 3 + boost::math::tools::digits<T>() / 4;
+   T lnn = log(n);
+   T term = 1;
+   T N = -lnn;
+   T D = 1;
+   T Hk = 0;
+   T one = 1;
+
+   for(unsigned k = 1;; ++k)
+   {
+      term *= n * n;
+      term /= k * k;
+      Hk += one / k;
+      N += term * (Hk - lnn);
+      D += term;
+
+      if(term < D * boost::math::tools::epsilon<T>())
+         break;
+   }
+   return N / D;
 }
 
 template <class T, int N> 
@@ -92,6 +169,11 @@
 template <class T, int N> 
 inline T calculate_ln_two(const mpl::int_<N>&BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))
 {
+   //
+   // Although there are good ways to calculate this from scratch, this hooks into
+   // T's own notion of log(2) which will hopefully be accurate to the full precision
+   // of T:
+   //
    BOOST_MATH_STD_USING
    return log(static_cast<T>(2));
 }
Modified: sandbox/math_constants/boost/math/constants/constants.hpp
==============================================================================
--- sandbox/math_constants/boost/math/constants/constants.hpp	(original)
+++ sandbox/math_constants/boost/math/constants/constants.hpp	2011-11-21 06:42:15 EST (Mon, 21 Nov 2011)
@@ -22,9 +22,6 @@
 #include <boost/mpl/and.hpp>
 #include <boost/mpl/int.hpp>
 #include <boost/type_traits/is_convertible.hpp>
-#ifdef BOOST_HAS_THREADS
-#  include <boost/thread/once.hpp>
-#endif
 
 namespace boost{ namespace math
 {
@@ -94,6 +91,73 @@
 #define BOOST_MATH_CONSTANT_THREAD_HELPER(name, prefix)
 #endif
 
+   namespace detail{
+
+      template <class Real>
+      Real convert_from_string(const char* p, const mpl::false_&)
+      {
+         return boost::lexical_cast<Real>(p);
+      }
+      template <class Real>
+      const char* convert_from_string(const char* p, const mpl::true_&)
+      {
+         return p;
+      }
+
+      template <class T, T (*F)(BOOST_EXPLICIT_TEMPLATE_TYPE_SPEC(T))>
+      struct constant_initializer
+      {
+         static void do_nothing()
+         {
+            init.do_nothing();
+         }
+      private:
+         struct initializer
+         {
+            initializer()
+            {
+               F(
+      #ifdef BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS
+                  0
+      #endif
+                  );
+            }
+            void do_nothing()const{}
+         };
+         static const initializer init;
+      };
+
+      template <class T, T (*F)(BOOST_EXPLICIT_TEMPLATE_TYPE_SPEC(T))>
+      typename constant_initializer<T, F>::initializer const constant_initializer<T, F>::init;
+
+      template <class T, int N, T (*F)(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(mpl::int_<N>) BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))>
+      struct constant_initializer2
+      {
+         static void do_nothing()
+         {
+            init.do_nothing();
+         }
+      private:
+         struct initializer
+         {
+            initializer()
+            {
+               F(
+      #ifdef BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS
+                  mpl::int_<N>() , 0
+      #endif
+                  );
+            }
+            void do_nothing()const{}
+         };
+         static const initializer init;
+      };
+
+      template <class T, int N, T (*F)(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(mpl::int_<N>) BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))>
+      typename constant_initializer2<T, N, F>::initializer const constant_initializer2<T, N, F>::init;
+
+   }
+
    #define BOOST_DEFINE_MATH_CONSTANT(name, x, y, exp)\
    namespace detail{\
    /* Forward declaration of the calculation method, just in case it's not been provided yet */ \
@@ -102,12 +166,12 @@
    /* The default implementations come next: */ \
    template <class T> inline T BOOST_JOIN(string_get_, name)(BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T))\
    {\
-      static const T result = ::boost::lexical_cast<T>(BOOST_STRINGIZE(BOOST_JOIN(BOOST_JOIN(x, y), BOOST_JOIN(e, exp))));\
+      static const T result = detail::convert_from_string<T>(BOOST_STRINGIZE(BOOST_JOIN(BOOST_JOIN(x, y), BOOST_JOIN(e, exp))), boost::is_convertible<const char*, T>());\
       return result;\
    }\
    template <class T> inline T BOOST_JOIN(get_, name)(const mpl::int_<construct_from_string>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T))\
    {\
-      BOOST_MATH_CONSTANT_THREAD_HELPER(name, string_)\
+      constant_initializer<T, & BOOST_JOIN(string_get_, name)<T> >::do_nothing();\
       return BOOST_JOIN(string_get_, name)<T>();\
    }\
    template <class T> inline BOOST_CONSTEXPR T BOOST_JOIN(get_, name)(const mpl::int_<construct_from_float>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))\
@@ -121,7 +185,7 @@
    { static const T result = BOOST_JOIN(calculate_, name)<T>(mpl::int_<N>()); return result; }\
    template <class T, int N> inline T BOOST_JOIN(get_, name)(const mpl::int_<N>& n BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))\
    {\
-      BOOST_MATH_CONSTANT_THREAD_HELPER(name, compute_)\
+      constant_initializer2<T, N, & BOOST_JOIN(compute_get_, name)<T, N> >::do_nothing();\
       return BOOST_JOIN(compute_get_, name)<T, N>(); \
    }\
    /* This one is for true arbitary precision, which may well vary at runtime: */ \
@@ -143,31 +207,27 @@
    namespace long_double_constants{ static const long double name = BOOST_JOIN(BOOST_JOIN(x, BOOST_JOIN(e, exp)), L); }\
    namespace constants{
 
-   BOOST_DEFINE_MATH_CONSTANT(pi, 3.141592653589793238462643383279502884197169399375105820974944, 59230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196, 0)
-   BOOST_DEFINE_MATH_CONSTANT(two_pi, 6.2831853071795864769252867665590057683943388015061, 0, 0)
-   BOOST_DEFINE_MATH_CONSTANT(one_div_two_pi, 0.70710678118654752440084436210484903928483593756084, 0, 0)
-   BOOST_DEFINE_MATH_CONSTANT(root_pi, 1.7724538509055160272981674833411451827975, 0, 0)
-   BOOST_DEFINE_MATH_CONSTANT(root_half_pi, 1.253314137315500251207882642405522626503, 0, 0)
-   BOOST_DEFINE_MATH_CONSTANT(root_two_pi, 2.506628274631000502415765284811045253007, 0, 0)
-   BOOST_DEFINE_MATH_CONSTANT(root_ln_four, 1.1774100225154746910115693264596996377473856893858205385225257565000, 2658854698492680841813836877081, 0)
-   BOOST_DEFINE_MATH_CONSTANT(e, 2.7182818284590452353602874713526624977572470936999595749669676, 27724076630353547594571382178525166427427466391932003059921817413596629043572900334295260595630738132328627943490763233829880753195251019011, 0)
-   BOOST_DEFINE_MATH_CONSTANT(half, 0.5, 0, 0)
-   BOOST_DEFINE_MATH_CONSTANT(euler,    0.577215664901532860606512090082402431042159335939923598805, 76723488486, 0)
-   BOOST_DEFINE_MATH_CONSTANT(root_two, 1.414213562373095048801688724209698078569671875376948073, 17667973799073247846210703885038753432764157273501384623091229702492483605585073721264412149709993583141322266592750559275579995050115278206, 0)
-   BOOST_DEFINE_MATH_CONSTANT(half_root_two, 0.70710678118654752440084436210484903928483593756084, 0, 0)
-   BOOST_DEFINE_MATH_CONSTANT(ln_two,   0.693147180559945309417232121458176568075500134360255254, 120680009493393621969694715605863326996418687, 0)
-   BOOST_DEFINE_MATH_CONSTANT(ln_ln_two,  -0.36651292058166432701243915823266946945426344783710526305367771367056, 16153193527385494558228566989083583025230453648347655663425171940646634, 0)
-   BOOST_DEFINE_MATH_CONSTANT(third, 0.3333333333333333333333333333333333333333333333333333333333333333333333, 3333333333333333333333333333333333333333333333333333333333333333333333333, 0)
-   BOOST_DEFINE_MATH_CONSTANT(twothirds, 0.66666666666666666666666666666666666666666666666666666666666666666666, 66666666666666666666666666666666666666666666666666666666666666666666667, 0)
-   BOOST_DEFINE_MATH_CONSTANT(pi_minus_three, 0.141592653589793238462643383279502884197169399375105820974944, 59230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196, 0)
-   BOOST_DEFINE_MATH_CONSTANT(four_minus_pi, 0.85840734641020676153735661672049711580283060062489417902505540769218359, 0, 0)
-   BOOST_DEFINE_MATH_CONSTANT(pow23_four_minus_pi, 0.79531676737159754434839533505680658072763917332771320544530223438582161, 0, 0)
-   BOOST_DEFINE_MATH_CONSTANT(exp_minus_half, 0.6065306597126334236037995349911804534419181354871869556828921587350565194137, 484239986476115079894560, 0)
-   BOOST_DEFINE_MATH_CONSTANT(one_div_root_two, 0.70710678118654752440084436210484903928483593756084, 0, 0)
-   BOOST_DEFINE_MATH_CONSTANT(one_div_root_two_pi, 0.39894228040143267793994605993438186847585863095671, 0, 0)
-
+BOOST_DEFINE_MATH_CONSTANT(pi, 3.141592653589793238462643383279502884, 1971693993751058209749445923078164062862089986280348253421170679821480865, 0);
+BOOST_DEFINE_MATH_CONSTANT(two_pi, 6.283185307179586476925286766559005768, 394338798750211641949889184615632812572417997256069650684234135964296173, 0);
+BOOST_DEFINE_MATH_CONSTANT(one_div_two_pi, 1.591549430918953357688837633725143620, 3445964574045644874766734405889679763422653509011380276625308595607284273, -1);
+BOOST_DEFINE_MATH_CONSTANT(root_pi, 1.772453850905516027298167483341145182, 7975494561223871282138077898529112845910321813749506567385446654162268236, 0);
+BOOST_DEFINE_MATH_CONSTANT(root_half_pi, 1.253314137315500251207882642405522626, 5034933703049691583149617881711468273039209874732979191890286330580049863, 0);
+BOOST_DEFINE_MATH_CONSTANT(root_two_pi, 2.506628274631000502415765284811045253,0069867406099383166299235763422936546078419749465958383780572661160099727, 0);
+BOOST_DEFINE_MATH_CONSTANT(root_ln_four, 1.177410022515474691011569326459699637, 7473856893858205385225257565000265885469849268084181383687708110674715786, 0);
+BOOST_DEFINE_MATH_CONSTANT(e, 2.718281828459045235360287471352662497, 7572470936999595749669676277240766303535475945713821785251664274274663919, 0);
+BOOST_DEFINE_MATH_CONSTANT(euler, 5.772156649015328606065120900824024310, 4215933593992359880576723488486772677766467093694706329174674951463144725, -1);
+BOOST_DEFINE_MATH_CONSTANT(root_two, 1.414213562373095048801688724209698078, 5696718753769480731766797379907324784621070388503875343276415727350138462, 0);
+BOOST_DEFINE_MATH_CONSTANT(half_root_two, 7.071067811865475244008443621048490392, 8483593768847403658833986899536623923105351942519376716382078636750692312, -1);
+BOOST_DEFINE_MATH_CONSTANT(ln_two, 6.931471805599453094172321214581765680, 7550013436025525412068000949339362196969471560586332699641868754200148102, -1);
+BOOST_DEFINE_MATH_CONSTANT(ln_ln_two, -3.665129205816643270124391582326694694, 5426344783710526305367771367056161531935273854945582285669890835830252305, -1);
+BOOST_DEFINE_MATH_CONSTANT(third, 3.333333333333333333333333333333333333, 3333333333333333333333333333333333333333333333333333333333333333333333333, -1);
+BOOST_DEFINE_MATH_CONSTANT(twothirds, 6.666666666666666666666666666666666666, 6666666666666666666666666666666666666666666666666666666666666666666666667, -1);
+BOOST_DEFINE_MATH_CONSTANT(pi_minus_three, 1.415926535897932384626433832795028841, 9716939937510582097494459230781640628620899862803482534211706798214808651, -1);
+BOOST_DEFINE_MATH_CONSTANT(four_minus_pi, 8.584073464102067615373566167204971158, 0283060062489417902505540769218359371379100137196517465788293201785191349, -1);
+BOOST_DEFINE_MATH_CONSTANT(pow23_four_minus_pi, 7.953167673715975443483953350568065807, 2763917332771320544530223438885626826751818759075800688860082843683980018, -1);
+BOOST_DEFINE_MATH_CONSTANT(exp_minus_half, 6.065306597126334236037995349911804534, 4191813548718695568289215873505651941374842399864761150798945602642378979, -1);
 
-  } // namespace constants
+} // namespace constants
 } // namespace math
 } // namespace boost
 
Modified: sandbox/math_constants/boost/math/constants/generate.hpp
==============================================================================
--- sandbox/math_constants/boost/math/constants/generate.hpp	(original)
+++ sandbox/math_constants/boost/math/constants/generate.hpp	2011-11-21 06:42:15 EST (Mon, 21 Nov 2011)
@@ -16,6 +16,8 @@
 #include <boost/math/bindings/mpfr.hpp>
 #elif defined(USE_MPREAL)
 #include <boost/math/bindings/mpreal.hpp>
+#elif defined(USE_CPP_FLOAT)
+#include <boost/multiprecision/cpp_float.hpp>
 #else
 #include <boost/math/bindings/rr.hpp>
 #endif
@@ -26,6 +28,8 @@
 typedef mpfr_class generator_type;
 #elif defined(USE_MPREAL)
 typedef mpfr::mpreal generator_type;
+#elif defined(USE_CPP_FLOAT)
+typedef boost::multiprecision::mp_number<boost::multiprecision::cpp_float<500> > generator_type;
 #else
 typedef ntl::RR generator_type;
 #endif
@@ -36,13 +40,15 @@
    mpfr_class::set_dprec(((200 + 1) * 1000L) / 301L);
 #elif defined(USE_MPREAL)
    mpfr::mpreal::set_default_prec(((200 + 1) * 1000L) / 301L);
+#elif defined(USE_CPP_FLOAT)
+   // Nothing to do, precision is already set.
 #else
    ntl::RR::SetPrecision(((200 + 1) * 1000L) / 301L);
    ntl::RR::SetOutputPrecision(102);
 #endif
    generator_type value = f(boost::mpl::int_<0>());
    std::stringstream os;
-   os << std::setprecision(102) << std::scientific;
+   os << std::setprecision(110) << std::scientific;
    os << value;
    std::string s = os.str();
    static const regex e("([+-]?\\d+(?:\\.\\d{0,36})?)(\\d*)(?:e([+-]?\\d+))?");
Modified: sandbox/math_constants/boost/math/constants/info.hpp
==============================================================================
--- sandbox/math_constants/boost/math/constants/info.hpp	(original)
+++ sandbox/math_constants/boost/math/constants/info.hpp	2011-11-21 06:42:15 EST (Mon, 21 Nov 2011)
@@ -108,6 +108,10 @@
       os <<
          "The constant will be constructed from a string (and the result cached).\n";
       break;
+   default:
+      os <<
+         "The constant will be calculated (and the result cached).\n";
+      break;
    }
    os << std::endl;
 #ifdef BOOST_MSVC
Added: sandbox/math_constants/libs/math/test/cpp_float_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/math_constants/libs/math/test/cpp_float_test.cpp	2011-11-21 06:42:15 EST (Mon, 21 Nov 2011)
@@ -0,0 +1,153 @@
+// cpp_float_test.cpp : Defines the entry point for the console application.
+//
+
+#include "stdafx.h"
+
+#include <boost/math/constants/constants.hpp>
+#include <boost/math/constants/info.hpp>
+#include <boost/multiprecision/cpp_float.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+template <class T>
+T brent_gamma()
+{
+   T n = 3 + boost::math::tools::digits<T>() / 4;
+   T lnn = log(n);
+   T term = 1;
+   T N = -lnn;
+   T D = 1;
+   T Hk = 0;
+   T one = 1;
+
+   for(unsigned k = 1;; ++k)
+   {
+      term *= n * n;
+      term /= k * k;
+      Hk += one / k;
+      N += term * (Hk - lnn);
+      D += term;
+
+      if(term < D * boost::math::tools::epsilon<T>())
+         break;
+   }
+   return N / D;
+}
+
+template <class T>
+T eg()
+{
+   T n = boost::math::tools::digits<T>() * 4;
+   T k_fact = 1;
+   T A = 0;
+   T B = 1;
+   T H = 0;
+   T n_k = 1;
+
+   for(unsigned k = 1;; ++k)
+   {
+      H += T(1) / k;
+      k_fact *= k;
+      n_k *= n;
+      T term = n_k / (k_fact * k_fact);
+      A += term * H;
+      B += term;
+
+      if((term < B * boost::math::tools::epsilon<T>()) && (term * H < A * boost::math::tools::epsilon<T>()))
+         break;
+   }
+   return A / B - log(n) / 2;
+}
+
+boost::multiprecision::mp_number<boost::multiprecision::cpp_float<1000> > log2 = 
+   "6.931471805599453094172321214581765680755001343602552541206800094933936219696947"
+   "15605863326996418687542001481020570685733685520235758130557032670751635075961930"
+   "72757082837143519030703862389167347112335011536449795523912047517268157493206515"
+   "55247341395258829504530070953263666426541042391578149520437404303855008019441706"
+   "41671518644712839968171784546957026271631064546150257207402481637773389638550695"
+   "26066834113727387372292895649354702576265209885969320196505855476470330679365443"
+   "25476327449512504060694381471046899465062201677204245245296126879465461931651746"
+   "81392672504103802546259656869144192871608293803172714367782654877566485085674077"
+   "64845146443994046142260319309673540257444607030809608504748663852313818167675143"
+   "86674766478908814371419854942315199735488037516586127535291661000710535582498794"
+   "14729509293113897155998205654392871700072180857610252368892132449713893203784393"
+   "53088774825970171559107088236836275898425891853530243634214367061189236789192372"
+   "31467232172053401649256872747782344535348e-1";
+
+boost::multiprecision::mp_number<boost::multiprecision::cpp_float<1000> > pi = 
+   "3.141592653589793238462643383279502884197169399375105820974944592307816406286208"
+   "99862803482534211706798214808651328230664709384460955058223172535940812848111745"
+   "02841027019385211055596446229489549303819644288109756659334461284756482337867831"
+   "65271201909145648566923460348610454326648213393607260249141273724587006606315588"
+   "17488152092096282925409171536436789259036001133053054882046652138414695194151160"
+   "94330572703657595919530921861173819326117931051185480744623799627495673518857527"
+   "24891227938183011949129833673362440656643086021394946395224737190702179860943702"
+   "77053921717629317675238467481846766940513200056812714526356082778577134275778960"
+   "91736371787214684409012249534301465495853710507922796892589235420199561121290219"
+   "60864034418159813629774771309960518707211349999998372978049951059731732816096318"
+   "59502445945534690830264252230825334468503526193118817101000313783875288658753320"
+   "83814206171776691473035982534904287554687311595628638823537875937519577818577805"
+   "32171226806613001927876611195909216420199";
+
+boost::multiprecision::mp_number<boost::multiprecision::cpp_float<1000> > euler = 
+   "5.772156649015328606065120900824024310421593359399235988057672348848677267776646"
+   "70936947063291746749514631447249807082480960504014486542836224173997644923536253"
+   "50033374293733773767394279259525824709491600873520394816567085323315177661152862"
+   "11995015079847937450857057400299213547861466940296043254215190587755352673313992"
+   "54012967420513754139549111685102807984234877587205038431093997361372553060889331"
+   "26760017247953783675927135157722610273492913940798430103417771778088154957066107"
+   "50101619166334015227893586796549725203621287922655595366962817638879272680132431"
+   "01047650596370394739495763890657296792960100901512519595092224350140934987122824"
+   "79497471956469763185066761290638110518241974448678363808617494551698927923018773"
+   "91072945781554316005002182844096053772434203285478367015177394398700302370339518"
+   "32869000155819398804270741154222781971652301107356583396734871765049194181230004"
+   "06546931429992977795693031005030863034185698032310836916400258929708909854868257"
+   "77364288253954925873629596133298574739302e-1";
+
+/*
+template <class T>
+void test()
+{
+   T p = boost::math::constants::pi<T>();
+   T err = fabs((p - T(pi)) / T(pi)) / boost::math::tools::epsilon<T>();
+   unsigned e = err.template convert_to<unsigned>();
+   BOOST_TEST(e < 30);
+}
+*/
+template <unsigned N>
+void test()
+{
+   typedef boost::multiprecision::mp_number<boost::multiprecision::cpp_float<N> > mp_t;
+   mp_t val = boost::math::constants::euler<mp_t>();
+   mp_t err = fabs((val - mp_t(euler)) / (mp_t(euler) * std::numeric_limits<mp_t>::epsilon()));
+   unsigned error = err.template convert_to<unsigned>();
+   BOOST_TEST(error < 30);
+
+   val = boost::math::constants::pi<mp_t>();
+   err = fabs((val - mp_t(pi)) / (mp_t(pi) * std::numeric_limits<mp_t>::epsilon()));
+   error = err.template convert_to<unsigned>();
+   BOOST_TEST(error < 30);
+
+   val = boost::math::constants::ln_two<mp_t>();
+   err = fabs((val - mp_t(log2)) / (mp_t(log2) * std::numeric_limits<mp_t>::epsilon()));
+   error = err.template convert_to<unsigned>();
+   BOOST_TEST(error < 30);
+}
+
+
+int _tmain(int argc, _TCHAR* argv[])
+{
+   boost::math::constants::print_info_on_type<boost::multiprecision::cpp_float_50>();
+   boost::math::constants::print_info_on_type<boost::multiprecision::cpp_float_100>();
+   boost::math::constants::print_info_on_type<boost::multiprecision::mp_number<boost::multiprecision::cpp_float<300> > >();
+
+   test<15>();
+   test<30>();
+   test<50>();
+   test<100>();
+   test<200>();
+   test<300>();
+   test<500>();
+
+	return boost::report_errors();
+}
+
Modified: sandbox/math_constants/libs/math/test/test_constant_generate.cpp
==============================================================================
--- sandbox/math_constants/libs/math/test/test_constant_generate.cpp	(original)
+++ sandbox/math_constants/libs/math/test/test_constant_generate.cpp	2011-11-21 06:42:15 EST (Mon, 21 Nov 2011)
@@ -10,6 +10,26 @@
 int main()
 {
    BOOST_CONSTANTS_GENERATE(pi);
+   BOOST_CONSTANTS_GENERATE(two_pi);
+   BOOST_CONSTANTS_GENERATE(one_div_two_pi);
+   BOOST_CONSTANTS_GENERATE(root_pi);
+   BOOST_CONSTANTS_GENERATE(root_half_pi);
+   BOOST_CONSTANTS_GENERATE(root_two_pi);
+   BOOST_CONSTANTS_GENERATE(root_ln_four);
+   BOOST_CONSTANTS_GENERATE(e);
+   BOOST_CONSTANTS_GENERATE(euler);
+   BOOST_CONSTANTS_GENERATE(root_two);
+   BOOST_CONSTANTS_GENERATE(half_root_two);
+   BOOST_CONSTANTS_GENERATE(ln_two);
+   BOOST_CONSTANTS_GENERATE(ln_ln_two);
+   BOOST_CONSTANTS_GENERATE(third);
+   BOOST_CONSTANTS_GENERATE(twothirds);
+   BOOST_CONSTANTS_GENERATE(pi_minus_three);
+   BOOST_CONSTANTS_GENERATE(four_minus_pi);
+   BOOST_CONSTANTS_GENERATE(pow23_four_minus_pi);
+   BOOST_CONSTANTS_GENERATE(exp_minus_half);
+   BOOST_CONSTANTS_GENERATE(one_div_root_two);
+   BOOST_CONSTANTS_GENERATE(one_div_root_two_pi);
    return 0;
 }
 
Modified: sandbox/math_constants/libs/math/test/test_constants.cpp
==============================================================================
--- sandbox/math_constants/libs/math/test/test_constants.cpp	(original)
+++ sandbox/math_constants/libs/math/test/test_constants.cpp	2011-11-21 06:42:15 EST (Mon, 21 Nov 2011)
@@ -8,8 +8,6 @@
 
 // test_constants.cpp
 
-#include <pch.hpp>
-
 #include <boost/math/concepts/real_concept.hpp> // for real_concept
 #include <boost/test/test_exec_monitor.hpp> // Boost.Test
 #include <boost/test/floating_point_comparison.hpp>
@@ -17,6 +15,7 @@
 #include <boost/math/constants/constants.hpp>
 #include <boost/math/tools/test.hpp> 
 #include <boost/static_assert.hpp>
+#include <boost/utility/enable_if.hpp>
 
 BOOST_STATIC_ASSERT((boost::is_same<boost::math::constants::construction_traits<float, boost::math::policies::policy<> >::type, boost::mpl::int_<boost::math::constants::construct_from_float> >::value));
 BOOST_STATIC_ASSERT((boost::is_same<boost::math::constants::construction_traits<double, boost::math::policies::policy<> >::type, boost::mpl::int_<boost::math::constants::construct_from_double> >::value));
@@ -41,7 +40,7 @@
 public:
    big_real_concept() {}
    template <class T>
-   big_real_concept(const T& t) : real_concept(t) {}
+   big_real_concept(const T& t, typename enable_if<is_convertible<T, real_concept> >::type* = 0) : real_concept(t) {}
 };
 
 }
@@ -63,7 +62,10 @@
    // Actual tolerance is never really smaller than epsilon for long double, even if some of our
    // test types pretend otherwise:
    //
+   typedef typename boost::math::constants::construction_traits<RealType, boost::math::policies::policy<> >::type construction_type;
    RealType tolerance = std::max(static_cast<RealType>(boost::math::tools::epsilon<long double>()), boost::math::tools::epsilon<RealType>()) * 2;  // double
+   if((construction_type::value == 0) && (boost::math::tools::digits<RealType>() > boost::math::constants::max_string_digits))
+      tolerance *= 30;  // allow a little extra tolerance for calculated constants.
    std::cout << "Tolerance for type " << typeid(RealType).name()  << " is " << tolerance << "." << std::endl;
 
    //typedef typename boost::math::policies::precision<RealType, boost::math::policies::policy<> >::type t1;
@@ -74,6 +76,10 @@
    using namespace std; // Help ADL of std exp, log...
    using std::exp;
 
+   RealType a = pi<RealType>();
+   RealType b = static_cast<RealType>(3.14159265358979323846264338327950288419716939937510L);
+   a = fabs((a-b) / b);
+
    BOOST_CHECK_CLOSE_FRACTION(static_cast<RealType>(3.14159265358979323846264338327950288419716939937510L), pi<RealType>(), tolerance); 
    BOOST_CHECK_CLOSE_FRACTION(static_cast<RealType>(3.14159265358979323846264338327950288419716939937510L), (pi<RealType, boost::math::policies::policy<> >)(), tolerance); 
    BOOST_CHECK_CLOSE_FRACTION(static_cast<RealType>(sqrt(3.14159265358979323846264338327950288419716939937510L)), root_pi<RealType>(), tolerance); 
Modified: sandbox/math_constants/libs/math/test/test_print_info_on_type.cpp
==============================================================================
--- sandbox/math_constants/libs/math/test/test_print_info_on_type.cpp	(original)
+++ sandbox/math_constants/libs/math/test/test_print_info_on_type.cpp	2011-11-21 06:42:15 EST (Mon, 21 Nov 2011)
@@ -8,6 +8,8 @@
 #include <boost/math/constants/info.hpp>
 #include <boost/math/concepts/real_concept.hpp>
 
+#include <boost/multiprecision/cpp_float.hpp>
+
 
 int main()
 {