Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r50344 - in trunk: boost/math/special_functions libs/math/test
From: john_at_[hidden]
Date: 2008-12-21 08:50:53


Author: johnmaddock
Date: 2008-12-21 08:50:52 EST (Sun, 21 Dec 2008)
New Revision: 50344
URL: http://svn.boost.org/trac/boost/changeset/50344

Log:
Fix expm1 error handling, and add additional tests to verify the correct behaviour.
Text files modified:
   trunk/boost/math/special_functions/expm1.hpp | 39 ++++++++++++++++++++++++++++++++++++---
   trunk/libs/math/test/log1p_expm1_test.cpp | 9 +++++++++
   2 files changed, 45 insertions(+), 3 deletions(-)

Modified: trunk/boost/math/special_functions/expm1.hpp
==============================================================================
--- trunk/boost/math/special_functions/expm1.hpp (original)
+++ trunk/boost/math/special_functions/expm1.hpp 2008-12-21 08:50:52 EST (Sun, 21 Dec 2008)
@@ -76,7 +76,15 @@
 
    T a = fabs(x);
    if(a > T(0.5L))
+ {
+ if(a >= tools::log_max_value<T>())
+ {
+ if(x > 0)
+ return policies::raise_overflow_error<T>("boost::math::expm1<%1%>(%1%)", 0, pol);
+ return -1;
+ }
       return exp(x) - T(1);
+ }
    if(a < tools::epsilon<T>())
       return x;
    detail::expm1_series<T> s(x);
@@ -92,13 +100,21 @@
 }
 
 template <class T, class P>
-T expm1_imp(T x, const mpl::int_<53>&, const P&)
+T expm1_imp(T x, const mpl::int_<53>&, const P& pol)
 {
    BOOST_MATH_STD_USING
 
    T a = fabs(x);
    if(a > T(0.5L))
+ {
+ if(a >= tools::log_max_value<T>())
+ {
+ if(x > 0)
+ return policies::raise_overflow_error<T>("boost::math::expm1<%1%>(%1%)", 0, pol);
+ return -1;
+ }
       return exp(x) - T(1);
+ }
    if(a < tools::epsilon<T>())
       return x;
 
@@ -111,13 +127,21 @@
 }
 
 template <class T, class P>
-T expm1_imp(T x, const mpl::int_<64>&, const P&)
+T expm1_imp(T x, const mpl::int_<64>&, const P& pol)
 {
    BOOST_MATH_STD_USING
 
    T a = fabs(x);
    if(a > T(0.5L))
+ {
+ if(a >= tools::log_max_value<T>())
+ {
+ if(x > 0)
+ return policies::raise_overflow_error<T>("boost::math::expm1<%1%>(%1%)", 0, pol);
+ return -1;
+ }
       return exp(x) - T(1);
+ }
    if(a < tools::epsilon<T>())
       return x;
 
@@ -146,13 +170,21 @@
 }
 
 template <class T, class P>
-T expm1_imp(T x, const mpl::int_<113>&, const P&)
+T expm1_imp(T x, const mpl::int_<113>&, const P& pol)
 {
    BOOST_MATH_STD_USING
 
    T a = fabs(x);
    if(a > T(0.5L))
+ {
+ if(a >= tools::log_max_value<T>())
+ {
+ if(x > 0)
+ return policies::raise_overflow_error<T>("boost::math::expm1<%1%>(%1%)", 0, pol);
+ return -1;
+ }
       return exp(x) - T(1);
+ }
    if(a < tools::epsilon<T>())
       return x;
 
@@ -272,3 +304,4 @@
 
 
 
+

Modified: trunk/libs/math/test/log1p_expm1_test.cpp
==============================================================================
--- trunk/libs/math/test/log1p_expm1_test.cpp (original)
+++ trunk/libs/math/test/log1p_expm1_test.cpp 2008-12-21 08:50:52 EST (Sun, 21 Dec 2008)
@@ -128,6 +128,14 @@
       BOOST_CHECK_EQUAL(boost::math::log1p(m_one), -std::numeric_limits<T>::infinity());
       BOOST_CHECK_EQUAL(boost::math::expm1(-std::numeric_limits<T>::infinity()), m_one);
       BOOST_CHECK_EQUAL(boost::math::expm1(std::numeric_limits<T>::infinity()), std::numeric_limits<T>::infinity());
+#ifndef __BORLANDC__
+ // When building with Borland's compiler, simply the *presence*
+ // of these tests cause other unrelated tests to fail!!! :-(
+ using namespace boost::math::policies;
+ typedef policy<overflow_error<throw_on_error> > pol;
+ BOOST_CHECK_THROW(boost::math::log1p(m_one, pol()), std::overflow_error);
+ BOOST_CHECK_THROW(boost::math::expm1(std::numeric_limits<T>::infinity(), pol()), std::overflow_error);
+#endif
    }
 }
 
@@ -156,3 +164,4 @@
 #endif
    return 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