$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r74057 - in sandbox/big_number: boost/math boost/math/big_number libs/math/config libs/math/test
From: john_at_[hidden]
Date: 2011-08-25 12:10:00
Author: johnmaddock
Date: 2011-08-25 12:09:57 EDT (Thu, 25 Aug 2011)
New Revision: 74057
URL: http://svn.boost.org/trac/boost/changeset/74057
Log:
Add conversion routines.
Add Jamfile.
Fix broken stream operators.
Added:
   sandbox/big_number/libs/math/config/
      - copied from r73943, /trunk/libs/math/config/
   sandbox/big_number/libs/math/config/has_gmp.cpp   (contents, props changed)
   sandbox/big_number/libs/math/config/has_mpfr.cpp   (contents, props changed)
   sandbox/big_number/libs/math/test/Jamfile.v2   (contents, props changed)
Text files modified: 
   sandbox/big_number/boost/math/big_number.hpp                 |    47 ++++++++++++++++++++++++++----          
   sandbox/big_number/boost/math/big_number/big_number_base.hpp |     6 ++--                                    
   sandbox/big_number/boost/math/big_number/default_ops.hpp     |    60 ++++++++++++++++++++++++++++++++++++++++
   sandbox/big_number/boost/math/big_number/e_float.hpp         |    28 ++++++++++++++++++                      
   sandbox/big_number/boost/math/big_number/gmp.hpp             |    28 ++++++++++++++++++                      
   sandbox/big_number/boost/math/big_number/mpfr.hpp            |    41 +++++++++++++++++++++++----             
   sandbox/big_number/libs/math/config/Jamfile.v2               |    16 ++++++++++                              
   sandbox/big_number/libs/math/config/has_e_float.cpp          |     6 ++-                                     
   sandbox/big_number/libs/math/test/test_arithmetic.cpp        |    31 ++++++++++++++++++++                    
   9 files changed, 243 insertions(+), 20 deletions(-)
Modified: sandbox/big_number/boost/math/big_number.hpp
==============================================================================
--- sandbox/big_number/boost/math/big_number.hpp	(original)
+++ sandbox/big_number/boost/math/big_number.hpp	2011-08-25 12:09:57 EDT (Thu, 25 Aug 2011)
@@ -326,6 +326,14 @@
    {
       return m_backend.str(digits, scientific);
    }
+   template <class T>
+   T convert_to()const
+   {
+      using big_num_default_ops::convert_to;
+      T result;
+      convert_to(&result, m_backend);
+      return result;
+   }
    //
    // Default precision:
    //
@@ -1190,22 +1198,47 @@
 {
    return 0 < detail::big_number_compare(a, b);
 }
+//
+// Because proto overloads these << operators, we need version that accept both
+// const and non-const RHS values, otherwise the proto version will be found
+// with unpleasant results... not only that, but the stream parameter has to be a template
+// otherwise the LHS of the expression would have to be *exactly* of type std::ostream
+// for the overload to be found (ie doesn't work for std::fstream etc unless we do this...)
+//
+template <class Stream, class Backend>
+inline typename enable_if<is_convertible<Stream*, std::ostream*>, std::ostream&>::type operator << (Stream& os, const big_number<Backend>& r)
+{
+   return os << r.str(static_cast<unsigned>(os.precision(), os.flags() & os.scientific));
+}
 
-template <class Backend>
-inline std::ostream& operator << (std::ostream& os, const big_number<Backend>& r)
+template <class Stream, class Backend>
+inline typename enable_if<is_convertible<Stream*, std::ostream*>, std::ostream&>::type operator << (Stream& os, big_number<Backend>& r)
 {
    return os << r.str(static_cast<unsigned>(os.precision(), os.flags() & os.scientific));
 }
-template <class Exp>
-inline std::ostream& operator << (std::ostream& os, const detail::big_number_exp<Exp>& r)
+
+namespace detail{
+
+template <class Stream, class Exp>
+inline typename enable_if<is_convertible<Stream*, std::ostream*>, std::ostream&>::type operator << (Stream& os, const big_number_exp<Exp>& r)
+{
+   typedef typename expression_type<detail::big_number_exp<Exp> >::type value_type;
+   value_type temp(r);
+   return os << temp;
+}
+
+template <class Stream, class Exp>
+inline typename enable_if<is_convertible<Stream*, std::ostream*>, std::ostream&>::type operator << (Stream& os, big_number_exp<Exp>& r)
 {
-   typedef typename detail::expression_type<Exp>::type value_type;
+   typedef typename expression_type<detail::big_number_exp<Exp> >::type value_type;
    value_type temp(r);
    return os << temp;
 }
 
-template <class Backend>
-inline std::istream& operator >> (std::istream& is, big_number<Backend>& r)
+}
+
+template <class Stream, class Backend>
+inline typename enable_if<is_convertible<Stream*, std::ostream*>, std::istream&>::type operator >> (Stream& is, big_number<Backend>& r)
 {
    std::string s;
    is >> s;
Modified: sandbox/big_number/boost/math/big_number/big_number_base.hpp
==============================================================================
--- sandbox/big_number/boost/math/big_number/big_number_base.hpp	(original)
+++ sandbox/big_number/boost/math/big_number/big_number_base.hpp	2011-08-25 12:09:57 EDT (Thu, 25 Aug 2011)
@@ -436,9 +436,9 @@
   : proto::extends<Expr, big_number_exp<Expr>, big_number_domain>
 {
 private:
-    typedef          proto::extends<Expr, big_number_exp<Expr>, big_number_domain>  base_type;
-    typedef          big_number_exp<Expr>                                           self_type;
-    typedef typename expression_type<self_type>::type                               number_type;
+    typedef          proto::extends<Expr, big_number_exp<Expr>, big_number_domain>      base_type;
+    typedef          big_number_exp<Expr>                                               self_type;
+    typedef typename remove_reference<typename expression_type<self_type>::type>::type  number_type;
     typedef          void (self_type::*unmentionable_type)();
     void unmentionable_proc(){}
     unmentionable_type boolean_context_from_terminal(const number_type* pval)const
Modified: sandbox/big_number/boost/math/big_number/default_ops.hpp
==============================================================================
--- sandbox/big_number/boost/math/big_number/default_ops.hpp	(original)
+++ sandbox/big_number/boost/math/big_number/default_ops.hpp	2011-08-25 12:09:57 EDT (Thu, 25 Aug 2011)
@@ -187,6 +187,66 @@
    return val.compare(static_cast<ui_type>(0));
 }
 
+template <class R, int b>
+struct has_enough_bits
+{
+   template <class T>
+   struct type : public mpl::and_<mpl::not_<is_same<R, T> >, mpl::bool_<std::numeric_limits<T>::digits >= b> >{};
+};
+
+template <class R>
+struct terminal
+{
+   terminal(const R& v) : value(v){}
+   terminal(){}
+   terminal& operator = (R val) {  value = val;  }
+   R value;
+   operator R()const {  return value;  }
+};
+
+template<class R, class B>
+struct calculate_next_larger_type
+{
+   typedef typename mpl::if_<
+      is_signed<R>,
+      typename B::signed_types,
+      typename mpl::if_<
+         is_unsigned<R>,
+         typename B::unsigned_types,
+         typename B::real_types
+      >::type
+   >::type list_type;
+   typedef typename has_enough_bits<R, std::numeric_limits<R>::digits>::template type<mpl::_> pred_type;
+   typedef typename mpl::find_if<
+      list_type,
+      pred_type
+   >::type iter_type;
+   typedef typename mpl::eval_if<
+      is_same<typename mpl::end<list_type>::type, iter_type>,
+      mpl::identity<terminal<R> >,
+      mpl::deref<iter_type>
+      >::type type;
+};
+
+template <class R, class B>
+inline void convert_to(R* result, const B& backend)
+{
+   typedef calculate_next_larger_type<R, B>::type next_type;
+   next_type n;
+   convert_to(&n, backend);
+   *result = static_cast<R>(n);
+}
+
+template <class R, class B>
+inline void convert_to(terminal<R>* result, const B& backend)
+{
+   //
+   // We ran out of types to try for the convertion, try
+   // a lexical_cast and hope for the best:
+   //
+   result->value = boost::lexical_cast<R>(backend.str(0, false));
+}
+
 //
 // Functions:
 //
Modified: sandbox/big_number/boost/math/big_number/e_float.hpp
==============================================================================
--- sandbox/big_number/boost/math/big_number/e_float.hpp	(original)
+++ sandbox/big_number/boost/math/big_number/e_float.hpp	2011-08-25 12:09:57 EDT (Thu, 25 Aug 2011)
@@ -10,6 +10,7 @@
 #include <boost/e_float/e_float.hpp>
 #include <boost/e_float/e_float_complex.hpp>
 #include <boost/e_float/e_float_elementary_math.hpp>
+#include <fstream>
 
 namespace boost{
 namespace math{
@@ -21,6 +22,17 @@
 {
    m_value.negate();
 }
+template<>
+inline std::string arithmetic_backend<efx::e_float>::str(unsigned digits, bool scientific)const
+{
+   std::fstream os;
+   os << std::setprecision(digits ? digits : efx::e_float::ef_digits + 5);
+   if(scientific)
+      os << std::scientific;
+   std::string result;
+   this->data().wr_string(result, os);
+   return result;
+}
 
 inline void abs(arithmetic_backend<efx::e_float>* result, const arithmetic_backend<efx::e_float>& arg)
 {
@@ -36,6 +48,22 @@
    return val.data().isneg() ? -1 : val.data().iszero() ? 0 : 1;
 }
 
+inline void convert_to(boost::uintmax_t* result, const arithmetic_backend<efx::e_float>& val)
+{
+   *result = val.data().extract_unsigned_long_long();
+}
+inline void convert_to(boost::intmax_t* result, const arithmetic_backend<efx::e_float>& val)
+{
+   *result = val.data().extract_signed_long_long();
+}
+inline void convert_to(double* result, const arithmetic_backend<efx::e_float>& val)
+{
+   *result = val.data().extract_double();
+}
+inline void convert_to(long double* result, const arithmetic_backend<efx::e_float>& val)
+{
+   *result = val.data().extract_long_double();
+}
 
 
 
Modified: sandbox/big_number/boost/math/big_number/gmp.hpp
==============================================================================
--- sandbox/big_number/boost/math/big_number/gmp.hpp	(original)
+++ sandbox/big_number/boost/math/big_number/gmp.hpp	2011-08-25 12:09:57 EDT (Thu, 25 Aug 2011)
@@ -553,6 +553,22 @@
    return mpf_sgn(val.data());
 }
 
+template <unsigned digits10>
+inline void convert_to(unsigned long* result, const gmp_real<digits10>& val)
+{
+   *result = mpf_get_ui(val.data());
+}
+template <unsigned digits10>
+inline void convert_to(long* result, const gmp_real<digits10>& val)
+{
+   *result = mpf_get_si(val.data());
+}
+template <unsigned digits10>
+inline void convert_to(double* result, const gmp_real<digits10>& val)
+{
+   *result = mpf_get_d(val.data());
+}
+
 //
 // Native non-member operations:
 //
@@ -1005,6 +1021,18 @@
 {
    return mpz_sgn(val.data());
 }
+inline void convert_to(unsigned long* result, const gmp_int& val)
+{
+   *result = mpz_get_ui(val.data());
+}
+inline void convert_to(long* result, const gmp_int& val)
+{
+   *result = mpz_get_si(val.data());
+}
+inline void convert_to(double* result, const gmp_int& val)
+{
+   *result = mpz_get_d(val.data());
+}
 
 inline void abs(gmp_int* result, const gmp_int& val)
 {
Modified: sandbox/big_number/boost/math/big_number/mpfr.hpp
==============================================================================
--- sandbox/big_number/boost/math/big_number/mpfr.hpp	(original)
+++ sandbox/big_number/boost/math/big_number/mpfr.hpp	2011-08-25 12:09:57 EDT (Thu, 25 Aug 2011)
@@ -159,10 +159,7 @@
    {
       std::string result;
       mp_exp_t e;
-      void *(*alloc_func_ptr) (size_t);
-      void *(*realloc_func_ptr) (void *, size_t, size_t);
-      void (*free_func_ptr) (void *, size_t);
-      const char* ps = mpfr_get_str (0, &e, 10, digits, m_data, MPFR_RNDN);
+      char* ps = mpfr_get_str (0, &e, 10, digits, m_data, MPFR_RNDN);
       std::ptrdiff_t sl = std::strlen(ps);
       unsigned chars = sl;
       if(sl == 0)
@@ -192,8 +189,7 @@
          if(e)
             result += "e" + lexical_cast<std::string>(e);
       }
-      mp_get_memory_functions(&alloc_func_ptr, &realloc_func_ptr, &free_func_ptr);
-      (*free_func_ptr)((void*)ps, sl + 1);
+      mpfr_free_str(ps);
       return result;
    }
    ~mpfr_real_imp()
@@ -555,6 +551,39 @@
    return mpfr_sgn(val.data());
 }
 
+template <unsigned digits10>
+inline void convert_to(unsigned long* result, const mpfr_real_backend<digits10>& val)
+{
+   *result = mpfr_get_ui(val.data(), MPFR_RNDN);
+}
+template <unsigned digits10>
+inline void convert_to(long* result, const mpfr_real_backend<digits10>& val)
+{
+   *result = mpfr_get_si(val.data(), MPFR_RNDN);
+}
+#ifdef _MPFR_H_HAVE_INTMAX_T
+template <unsigned digits10>
+inline void convert_to(boost::uintmax_t* result, const mpfr_real_backend<digits10>& val)
+{
+   *result = mpfr_get_uj(val.data(), MPFR_RNDN);
+}
+template <unsigned digits10>
+inline void convert_to(boost::intmax_t* result, const mpfr_real_backend<digits10>& val)
+{
+   *result = mpfr_get_sj(val.data(), MPFR_RNDN);
+}
+#endif
+template <unsigned digits10>
+inline void convert_to(double* result, const mpfr_real_backend<digits10>& val)
+{
+   *result = mpfr_get_d(val.data(), MPFR_RNDN);
+}
+template <unsigned digits10>
+inline void convert_to(long double* result, const mpfr_real_backend<digits10>& val)
+{
+   *result = mpfr_get_ld(val.data(), MPFR_RNDN);
+}
+
 //
 // Native non-member operations:
 //
Modified: sandbox/big_number/libs/math/config/Jamfile.v2
==============================================================================
--- /trunk/libs/math/config/Jamfile.v2	(original)
+++ sandbox/big_number/libs/math/config/Jamfile.v2	2011-08-25 12:09:57 EDT (Thu, 25 Aug 2011)
@@ -8,7 +8,15 @@
 
 local ntl-path = [ modules.peek : NTL_PATH ] ;
 local gmp_path = [ modules.peek : GMP_PATH ] ;
-local e_float_path = [ modules.peek : E_FLOAT_PATH ] ;
+local mpfr_path = [ modules.peek : MPFR_PATH ] ;
+local e_float_path = [ modules.peek : BOOST_E_FLOAT_PATH ] ;
+
+if ! $(e_float_path)
+{
+   e_float_path = ../../../../e_float ;
+}
+
+ECHO $(BOOST_E_FLOAT_PATH)
 
 obj has_long_double_support : has_long_double_support.cpp ;
 obj has_mpfr_class : has_mpfr_class.cpp :
@@ -21,6 +29,10 @@
 obj has_gcc_visibility : has_gcc_visibility.cpp :
       <toolset>gcc:<cxxflags>-fvisibility=hidden <toolset>gcc:<cxxflags>-Werror ;
 obj has_e_float : has_e_float.cpp : <include>$(e_float_path) ;
+obj has_gmp : has_gmp.cpp :
+      <include>$(gmp_path) <include>$(gmp_path)/mpfr <include>$(gmp_path)/gmpfrxx ;
+obj has_mpfr : has_mpfr.cpp :
+      <include>$(mpfr_path) <include>$(gmp_path)/mpfr <include>$(gmp_path)/gmpfrxx ;
 
 explicit has_long_double_support ;
 explicit has_mpfr_class ;
@@ -29,3 +41,5 @@
 explicit has_gmpxx ;
 explicit has_gcc_visibility ;
 explicit has_e_float ;
+explicit has_gmp ;
+explicit has_mpfr ;
Modified: sandbox/big_number/libs/math/config/has_e_float.cpp
==============================================================================
--- /trunk/libs/math/config/has_e_float.cpp	(original)
+++ sandbox/big_number/libs/math/config/has_e_float.cpp	2011-08-25 12:09:57 EDT (Thu, 25 Aug 2011)
@@ -10,6 +10,8 @@
 
 #define E_FLOAT_TYPE_EFX
 
-#include <e_float/e_float.h>
-#include <functions/functions.h>
+#include <boost/e_float/e_float.hpp>
+#include <boost/e_float/e_float_complex.hpp>
+#include <boost/e_float/e_float_elementary_math.hpp>
+
 
Added: sandbox/big_number/libs/math/config/has_gmp.cpp
==============================================================================
--- (empty file)
+++ sandbox/big_number/libs/math/config/has_gmp.cpp	2011-08-25 12:09:57 EDT (Thu, 25 Aug 2011)
@@ -0,0 +1,7 @@
+//  Copyright John Maddock 2008.
+//  Use, modification and distribution are subject to the
+//  Boost Software License, Version 1.0. (See accompanying file
+//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <gmp.h>
+
Added: sandbox/big_number/libs/math/config/has_mpfr.cpp
==============================================================================
--- (empty file)
+++ sandbox/big_number/libs/math/config/has_mpfr.cpp	2011-08-25 12:09:57 EDT (Thu, 25 Aug 2011)
@@ -0,0 +1,7 @@
+//  Copyright John Maddock 2008.
+//  Use, modification and distribution are subject to the
+//  Boost Software License, Version 1.0. (See accompanying file
+//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <mpfr.h>
+
Added: sandbox/big_number/libs/math/test/Jamfile.v2
==============================================================================
--- (empty file)
+++ sandbox/big_number/libs/math/test/Jamfile.v2	2011-08-25 12:09:57 EDT (Thu, 25 Aug 2011)
@@ -0,0 +1,166 @@
+# copyright John Maddock 2008
+# Distributed under the Boost Software License, Version 1.0. 
+# (See accompanying file LICENSE_1_0.txt or copy at 
+# http://www.boost.org/LICENSE_1_0.txt.
+
+import modules ;
+import path ;
+
+local ntl-path = [ modules.peek : NTL_PATH ] ;
+local gmp_path = [ modules.peek : GMP_PATH ] ;
+local mpfr_path = [ modules.peek : MPFR_PATH ] ;
+local e_float_path = [ modules.peek : BOOST_E_FLOAT_PATH ] ;
+
+if ! $(e_float_path)
+{
+   e_float_path = ../../../../e_float ;
+}
+
+project : requirements 
+   <include>$(gmp_path) 
+   <include>$(gmp_path)/mpfr 
+   <include>$(gmp_path)/gmpfrxx 
+   <include>$(mpfr_path)
+   <include>../../.. 
+   <include>$(e_float_path) 
+   <search>$(gmp_path) 
+   <search>$(mpfr_path) 
+   <search>$(mpfr_path)/build.vc10/lib/Win32/Debug
+   <toolset>msvc:<runtime-link>static
+   <define>E_FLOAT_DIGITS10=100
+   <define>E_FLOAT_TYPE_EFX
+   ;
+
+lib gmp ;
+lib mpfr ;
+
+E_FLOAT_SRC =    [ GLOB $(e_float_path)/libs/e_float/src/e_float : *.cpp ]
+   [ GLOB $(e_float_path)/libs/e_float/src/e_float/efx : *.cpp ]
+   [ GLOB $(e_float_path)/libs/e_float/src/functions/constants : *.cpp ]
+   [ GLOB $(e_float_path)/libs/e_float/src/functions/elementary : *.cpp ]
+   [ GLOB $(e_float_path)/libs/e_float/src/functions/gamma : *.cpp ]
+   [ GLOB $(e_float_path)/libs/e_float/src/functions/integer : *.cpp ]
+   [ GLOB $(e_float_path)/libs/e_float/src/functions/tables : *.cpp ]
+   [ GLOB $(e_float_path)/libs/e_float/src/functions/zeta : *.cpp ]
+   [ GLOB $(e_float_path)/libs/e_float/src/generic_functions/constants : *.cpp ]
+   [ GLOB $(e_float_path)/libs/e_float/src/generic_functions/elementary : *.cpp ]
+   [ GLOB $(e_float_path)/libs/e_float/src/utility : *.cpp ]
+ ;
+
+lib e_float : $(E_FLOAT_SRC)
+   :
+   [ check-target-builds ../config//has_e_float : : <build>no ]
+   ;
+
+run test_arithmetic.cpp
+        : # command line
+        : # input files
+        : # requirements
+	      <define>TEST_BACKEND
+        : test_arithmetic_backend_concept ;
+
+run test_arithmetic.cpp gmp
+        : # command line
+        : # input files
+        : # requirements
+	      <define>TEST_MPF50
+         [ check-target-builds ../config//has_gmp : : <build>no ]
+        : test_arithmetic_mpf50 ;
+
+run test_arithmetic.cpp gmp
+        : # command line
+        : # input files
+        : # requirements
+	      <define>TEST_MPF
+         [ check-target-builds ../config//has_gmp : : <build>no ]
+        : test_arithmetic_mpf ;
+
+run test_arithmetic.cpp gmp
+        : # command line
+        : # input files
+        : # requirements
+	      <define>TEST_MPZ
+         [ check-target-builds ../config//has_gmp : : <build>no ]
+        : test_arithmetic_mpz ;
+
+run test_arithmetic.cpp mpfr gmp
+        : # command line
+        : # input files
+        : # requirements
+	      <define>TEST_MPFR
+         [ check-target-builds ../config//has_mpfr : : <build>no ]
+        : test_arithmetic_mpfr ;
+
+run test_arithmetic.cpp mpfr gmp
+        : # command line
+        : # input files
+        : # requirements
+	      <define>TEST_MPFR_50
+         [ check-target-builds ../config//has_mpfr : : <build>no ]
+        : test_arithmetic_mpfr_50 ;
+
+run test_arithmetic.cpp $(E_FLOAT_SRC)
+        : # command line
+        : # input files
+        : # requirements
+	      <define>TEST_E_FLOAT
+         [ check-target-builds ../config//has_e_float : : <build>no ]
+        : test_arithmetic_e_float ;
+
+run test_numeric_limits.cpp
+        : # command line
+        : # input files
+        : # requirements
+	      <define>TEST_BACKEND
+        : test_numeric_limits_backend_concept ;
+
+run test_numeric_limits.cpp gmp
+        : # command line
+        : # input files
+        : # requirements
+	      <define>TEST_MPF50
+         [ check-target-builds ../config//has_gmp : : <build>no ]
+        : test_numeric_limits_mpf50 ;
+
+run test_numeric_limits.cpp gmp
+        : # command line
+        : # input files
+        : # requirements
+	      <define>TEST_MPF
+         [ check-target-builds ../config//has_gmp : : <build>no ]
+        : test_numeric_limits_mpf ;
+
+run test_numeric_limits.cpp gmp
+        : # command line
+        : # input files
+        : # requirements
+	      <define>TEST_MPZ
+         [ check-target-builds ../config//has_gmp : : <build>no ]
+        : test_numeric_limits_mpz ;
+
+run test_numeric_limits.cpp mpfr
+        : # command line
+        : # input files
+        : # requirements
+	      <define>TEST_MPFR
+         [ check-target-builds ../config//has_mpfr : : <build>no ]
+        : test_numeric_limits_mpfr ;
+
+run test_numeric_limits.cpp mpfr
+        : # command line
+        : # input files
+        : # requirements
+	      <define>TEST_MPFR_50
+         [ check-target-builds ../config//has_mpfr : : <build>no ]
+        : test_numeric_limits_mpfr_50 ;
+
+run test_numeric_limits.cpp $(E_FLOAT_SRC)
+        : # command line
+        : # input files
+        : # requirements
+	      <define>TEST_E_FLOAT
+         [ check-target-builds ../config//has_e_float : : <build>no ]
+        : test_numeric_limits_e_float ;
+
+
+
Modified: sandbox/big_number/libs/math/test/test_arithmetic.cpp
==============================================================================
--- sandbox/big_number/libs/math/test/test_arithmetic.cpp	(original)
+++ sandbox/big_number/libs/math/test/test_arithmetic.cpp	2011-08-25 12:09:57 EDT (Thu, 25 Aug 2011)
@@ -174,7 +174,6 @@
 void test_real_ops(const boost::mpl::true_&)
 {
 #if defined(TEST_MPF) || defined(TEST_MPF_50)
-   std::cout << "Root2 = " << sqrt(Real(2)) << std::endl;
    BOOST_TEST(abs(Real(2)) == 2);
    BOOST_TEST(abs(Real(-2)) == 2);
    BOOST_TEST(fabs(Real(2)) == 2);
@@ -203,6 +202,16 @@
 #endif
 }
 
+#ifdef TEST_E_FLOAT
+
+template <class T>
+struct lexical_cast_target_type
+{
+   typedef long double type;
+};
+
+#else
+
 template <class T>
 struct lexical_cast_target_type
 {
@@ -217,6 +226,8 @@
    >::type type;
 };
 
+#endif
+
 template <class Real, class Num>
 void test_negative_mixed(boost::mpl::true_ const&)
 {
@@ -312,6 +323,10 @@
    BOOST_TEST(Real(n2) == n2);
    BOOST_TEST(Real(n3) == n3);
    BOOST_TEST(Real(n4) == n4);
+   BOOST_TEST(Real(n1).template convert_to<Num>() == n1);
+   BOOST_TEST(Real(n2).template convert_to<Num>() == n2);
+   BOOST_TEST(Real(n3).template convert_to<Num>() == n3);
+   BOOST_TEST(Real(n4).template convert_to<Num>() == n4);
    BOOST_TEST(n1 == Real(n1));
    BOOST_TEST(n2 == Real(n2));
    BOOST_TEST(n3 == Real(n3));
@@ -689,6 +704,20 @@
    {
       BOOST_ERROR("Unexpected non-zero result");
    }
+   //
+   // Test iostreams:
+   //
+   std::stringstream ss;
+   a = 20;
+   b = 2;
+   ss << a;
+   ss >> c;
+   BOOST_TEST(a == c);
+   ss.clear();
+   ss << a + b;
+   ss >> c;
+   BOOST_TEST(c == 22);
+   BOOST_TEST(c == a + b);
 }