Boost logo

Boost-Commit :

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);
 }
 
 


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk