Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r83619 - in trunk: boost/multiprecision/detail/functions libs/multiprecision/test
From: john_at_[hidden]
Date: 2013-03-28 07:27:09


Author: johnmaddock
Date: 2013-03-28 07:27:08 EDT (Thu, 28 Mar 2013)
New Revision: 83619
URL: http://svn.boost.org/trac/boost/changeset/83619

Log:
Fix bug(s) that cause variable reuse in function calls to fail.
Add additional test cases.
Fixes #8326.
Text files modified:
   trunk/boost/multiprecision/detail/functions/pow.hpp | 9 +++
   trunk/boost/multiprecision/detail/functions/trig.hpp | 9 ++
   trunk/libs/multiprecision/test/test_arithmetic.hpp | 115 +++++++++++++++++++++++++++++++++++++--
   3 files changed, 126 insertions(+), 7 deletions(-)

Modified: trunk/boost/multiprecision/detail/functions/pow.hpp
==============================================================================
--- trunk/boost/multiprecision/detail/functions/pow.hpp (original)
+++ trunk/boost/multiprecision/detail/functions/pow.hpp 2013-03-28 07:27:08 EDT (Thu, 28 Mar 2013)
@@ -25,6 +25,14 @@
 
    typedef typename boost::multiprecision::detail::canonical<U, T>::type int_type;
 
+ if(&result == &t)
+ {
+ T temp;
+ pow_imp(temp, t, p, mpl::false_());
+ result = temp;
+ return;
+ }
+
    // This will store the result.
    if(U(p % U(2)) != U(0))
    {
@@ -411,6 +419,7 @@
       T t;
       eval_pow(t, x, a);
       result = t;
+ return;
    }
 
    if(a.compare(si_type(1)) == 0)

Modified: trunk/boost/multiprecision/detail/functions/trig.hpp
==============================================================================
--- trunk/boost/multiprecision/detail/functions/trig.hpp (original)
+++ trunk/boost/multiprecision/detail/functions/trig.hpp 2013-03-28 07:27:08 EDT (Thu, 28 Mar 2013)
@@ -221,7 +221,7 @@
    if(&result == &x)
    {
       T temp;
- eval_sin(temp, x);
+ eval_cos(temp, x);
       result = temp;
       return;
    }
@@ -361,6 +361,13 @@
 void eval_tan(T& result, const T& x)
 {
    BOOST_STATIC_ASSERT_MSG(number_category<T>::value == number_kind_floating_point, "The tan function is only valid for floating point types.");
+ if(&result == &x)
+ {
+ T temp;
+ eval_tan(temp, x);
+ result = temp;
+ return;
+ }
    T t;
    eval_sin(result, x);
    eval_cos(t, x);

Modified: trunk/libs/multiprecision/test/test_arithmetic.hpp
==============================================================================
--- trunk/libs/multiprecision/test/test_arithmetic.hpp (original)
+++ trunk/libs/multiprecision/test/test_arithmetic.hpp 2013-03-28 07:27:08 EDT (Thu, 28 Mar 2013)
@@ -641,6 +641,107 @@
 }
 
 template <class Real, class T>
+void test_float_funcs(const T&){}
+
+template <class Real>
+void test_float_funcs(const boost::mpl::true_&)
+{
+ if(boost::multiprecision::is_interval_number<Real>::value)
+ return;
+ //
+ // Test variable reuse in function calls, see https://svn.boost.org/trac/boost/ticket/8326
+ //
+ Real a(2), b(10);
+ a = pow(a, b);
+ BOOST_CHECK_EQUAL(a, 1024);
+ a = 2;
+ b = pow(a, b);
+ BOOST_CHECK_EQUAL(b, 1024);
+ b = 10;
+ a = pow(a, 10);
+ BOOST_CHECK_EQUAL(a, 1024);
+ a = -2;
+ a = abs(a);
+ BOOST_CHECK_EQUAL(a, 2);
+ a = -2;
+ a = fabs(a);
+ BOOST_CHECK_EQUAL(a, 2);
+ a = 2.5;
+ a = floor(a);
+ BOOST_CHECK_EQUAL(a, 2);
+ a = 2.5;
+ a = ceil(a);
+ BOOST_CHECK_EQUAL(a, 3);
+ a = 2.5;
+ a = trunc(a);
+ BOOST_CHECK_EQUAL(a, 2);
+ a = 2.25;
+ a = round(a);
+ BOOST_CHECK_EQUAL(a, 2);
+ a = 2;
+ a = ldexp(a, 1);
+ BOOST_CHECK_EQUAL(a, 4);
+ int i;
+ a = frexp(a, &i);
+ BOOST_CHECK_EQUAL(a, 0.5);
+
+ Real tol = std::numeric_limits<Real>::epsilon() * 3;
+ a = 4;
+ a = sqrt(a);
+ BOOST_CHECK_CLOSE_FRACTION(a, 2, tol);
+ a = 3;
+ a = exp(a);
+ BOOST_CHECK_CLOSE_FRACTION(a, Real(exp(Real(3))), tol);
+ a = 3;
+ a = log(a);
+ BOOST_CHECK_CLOSE_FRACTION(a, Real(log(Real(3))), tol);
+ a = 3;
+ a = log10(a);
+ BOOST_CHECK_CLOSE_FRACTION(a, Real(log10(Real(3))), tol);
+
+ a = 0.5;
+ a = sin(a);
+ BOOST_CHECK_CLOSE_FRACTION(a, Real(sin(Real(0.5))), tol);
+ a = 0.5;
+ a = cos(a);
+ BOOST_CHECK_CLOSE_FRACTION(a, Real(cos(Real(0.5))), tol);
+ a = 0.5;
+ a = tan(a);
+ BOOST_CHECK_CLOSE_FRACTION(a, Real(tan(Real(0.5))), tol);
+ a = 0.5;
+ a = asin(a);
+ BOOST_CHECK_CLOSE_FRACTION(a, Real(asin(Real(0.5))), tol);
+ a = 0.5;
+ a = acos(a);
+ BOOST_CHECK_CLOSE_FRACTION(a, Real(acos(Real(0.5))), tol);
+ a = 0.5;
+ a = atan(a);
+ BOOST_CHECK_CLOSE_FRACTION(a, Real(atan(Real(0.5))), tol);
+ a = 0.5;
+ a = sinh(a);
+ BOOST_CHECK_CLOSE_FRACTION(a, Real(sinh(Real(0.5))), tol);
+ a = 0.5;
+ a = cosh(a);
+ BOOST_CHECK_CLOSE_FRACTION(a, Real(cosh(Real(0.5))), tol);
+ a = 0.5;
+ a = tanh(a);
+ BOOST_CHECK_CLOSE_FRACTION(a, Real(tanh(Real(0.5))), tol);
+ a = 4;
+ b = 2;
+ a = fmod(a, b);
+ BOOST_CHECK_CLOSE_FRACTION(a, Real(fmod(Real(4), Real(2))), tol);
+ a = 4;
+ b = fmod(a, b);
+ BOOST_CHECK_CLOSE_FRACTION(b, Real(fmod(Real(4), Real(2))), tol);
+ b = 2;
+ a = atan2(a, b);
+ BOOST_CHECK_CLOSE_FRACTION(a, Real(atan2(Real(4), Real(2))), tol);
+ a = 4;
+ b = atan2(a, b);
+ BOOST_CHECK_CLOSE_FRACTION(b, Real(atan2(Real(4), Real(2))), tol);
+}
+
+template <class Real, class T>
 void test_float_ops(const T&){}
 
 template <class Real>
@@ -662,15 +763,15 @@
    BOOST_CHECK_EQUAL(ldexp(Real(2), 5) , 64);
    BOOST_CHECK_EQUAL(ldexp(Real(2), -5) , Real(2) / 32);
    Real v(512);
- int exp;
- Real r = frexp(v, &exp);
+ int exponent;
+ Real r = frexp(v, &exponent);
    BOOST_CHECK_EQUAL(r , 0.5);
- BOOST_CHECK_EQUAL(exp , 10);
+ BOOST_CHECK_EQUAL(exponent , 10);
    BOOST_CHECK_EQUAL(v , 512);
    v = 1 / v;
- r = frexp(v, &exp);
+ r = frexp(v, &exponent);
    BOOST_CHECK_EQUAL(r , 0.5);
- BOOST_CHECK_EQUAL(exp , -8);
+ BOOST_CHECK_EQUAL(exponent , -8);
    typedef typename Real::backend_type::exponent_type e_type;
    BOOST_CHECK_EQUAL(ldexp(Real(2), e_type(5)) , 64);
    BOOST_CHECK_EQUAL(ldexp(Real(2), e_type(-5)) , Real(2) / 32);
@@ -685,7 +786,7 @@
    BOOST_CHECK_EQUAL(r , 0.5);
    BOOST_CHECK_EQUAL(exp2 , -8);
    //
- // pow and exp:
+ // pow and exponent:
    //
    v = 3.25;
    r = pow(v, 0);
@@ -719,6 +820,8 @@
          BOOST_CHECK_THROW(Real(Real(20) / 0u), std::overflow_error);
       }
    }
+
+ test_float_funcs<Real>(boost::mpl::bool_<std::numeric_limits<Real>::is_specialized>());
 }
 
 template <class T>


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