$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r74736 - in sandbox/big_number: boost/multiprecision/detail/functions libs/multiprecision/test
From: john_at_[hidden]
Date: 2011-10-05 07:26:32
Author: johnmaddock
Date: 2011-10-05 07:26:31 EDT (Wed, 05 Oct 2011)
New Revision: 74736
URL: http://svn.boost.org/trac/boost/changeset/74736
Log:
Change log to give correct answer for log(1) and to not subtract towards the correct answer when that answer is small.  Also improves series convergence.
Text files modified: 
   sandbox/big_number/boost/multiprecision/detail/functions/pow.hpp |    26 +++++++++++++++++++++-----              
   sandbox/big_number/libs/multiprecision/test/test_log.cpp         |     1 +                                       
   2 files changed, 22 insertions(+), 5 deletions(-)
Modified: sandbox/big_number/boost/multiprecision/detail/functions/pow.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/detail/functions/pow.hpp	(original)
+++ sandbox/big_number/boost/multiprecision/detail/functions/pow.hpp	2011-10-05 07:26:31 EDT (Wed, 05 Oct 2011)
@@ -264,14 +264,24 @@
    typedef typename boost::multiprecision::detail::canonical<unsigned, T>::type ui_type;
    typedef typename T::exponent_type exp_type;
    typedef typename boost::multiprecision::detail::canonical<exp_type, T>::type canonical_exp_type;
+   typedef typename mpl::front<typename T::real_types>::type fp_type;
 
    exp_type e;
    T t;
    eval_frexp(t, arg, &e);
+   bool alternate = false;
+
+   if(t.compare(fp_type(2) / fp_type(3)) <= 0)
+   {
+      alternate = true;
+      eval_ldexp(t, t, 1);
+      --e;
+   }
    
    multiply(result, get_constant_ln2<T>(), canonical_exp_type(e));
-   subtract(t, ui_type(1)); /* -0.5 <= t <= 0 */
-   t.negate(); /* 0 <= t <= 0.5 */
+   subtract(t, ui_type(1)); /* -0.3 <= t <= 0.3 */
+   if(!alternate)
+      t.negate(); /* 0 <= t <= 0.33333 */
    T pow = t;
    T lim;
    T t2;
@@ -279,7 +289,10 @@
    if(get_sign(lim) < 0)
       lim.negate();
 
-   subtract(result, t);
+   if(alternate)
+      add(result, t);
+   else
+      subtract(result, t);
 
    ui_type k = 1;
    do
@@ -287,7 +300,10 @@
       ++k;
       multiply(pow, t);
       divide(t2, pow, k);
-      subtract(result, t2);
-   }while(lim.compare(t2) <= 0);
+      if(alternate && ((k & 1) != 0))
+         add(result, t2);
+      else
+         subtract(result, t2);
+   }while(lim.compare(t2) < 0);
 }
 
Modified: sandbox/big_number/libs/multiprecision/test/test_log.cpp
==============================================================================
--- sandbox/big_number/libs/multiprecision/test/test_log.cpp	(original)
+++ sandbox/big_number/libs/multiprecision/test/test_log.cpp	2011-10-05 07:26:31 EDT (Wed, 05 Oct 2011)
@@ -159,6 +159,7 @@
    }
    std::cout << "Max error was: " << max_err << std::endl;
    BOOST_TEST(max_err < 10);
+   BOOST_TEST(log(T(1)) == 0);
 }