Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r83874 - in trunk: boost/multiprecision/detail libs/multiprecision/test libs/multiprecision/test/math
From: john_at_[hidden]
Date: 2013-04-13 12:53:03


Author: johnmaddock
Date: 2013-04-13 12:53:01 EDT (Sat, 13 Apr 2013)
New Revision: 83874
URL: http://svn.boost.org/trac/boost/changeset/83874

Log:
Fixes to get the float128 tests passing with Intel C++ 13.0.
Text files modified:
   trunk/boost/multiprecision/detail/float_string_cvt.hpp | 56 +++++++++++++++++++++++++++++++++++++--
   trunk/libs/multiprecision/test/math/test_bessel_k.cpp | 10 ++++++
   trunk/libs/multiprecision/test/math/test_ellint_3.cpp | 9 ++++++
   trunk/libs/multiprecision/test/math/test_erf.cpp | 9 ++++++
   trunk/libs/multiprecision/test/math/test_expint.cpp | 9 ++++++
   trunk/libs/multiprecision/test/math/test_gamma.cpp | 9 ++++++
   trunk/libs/multiprecision/test/math/test_hermite.cpp | 9 ++++++
   trunk/libs/multiprecision/test/math/test_ibeta.cpp | 9 ++++++
   trunk/libs/multiprecision/test/math/test_ibeta_2.cpp | 9 ++++++
   trunk/libs/multiprecision/test/math/test_zeta.cpp | 9 ++++++
   trunk/libs/multiprecision/test/test_cos.cpp | 8 +++++
   trunk/libs/multiprecision/test/test_exp.cpp | 4 ++
   trunk/libs/multiprecision/test/test_float_io.cpp | 10 +++++--
   trunk/libs/multiprecision/test/test_log.cpp | 4 ++
   trunk/libs/multiprecision/test/test_sqrt.cpp | 4 ++
   15 files changed, 161 insertions(+), 7 deletions(-)

Modified: trunk/boost/multiprecision/detail/float_string_cvt.hpp
==============================================================================
--- trunk/boost/multiprecision/detail/float_string_cvt.hpp (original)
+++ trunk/boost/multiprecision/detail/float_string_cvt.hpp 2013-04-13 12:53:01 EDT (Sat, 13 Apr 2013)
@@ -2,6 +2,12 @@
 // Copyright 2013 John Maddock. 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_
+//
+// Generic routines for converting floating point values to and from decimal strings.
+// Note that these use "naive" algorithms which result in rounding error - so they
+// do not round trip to and from the string representation (but should only be out
+// in the last bit).
+//
 
 #ifndef BOOST_MP_FLOAT_STRING_CVT_HPP
 #define BOOST_MP_FLOAT_STRING_CVT_HPP
@@ -12,6 +18,9 @@
 
 inline void round_string_up_at(std::string& s, int pos)
 {
+ //
+ // Rounds up a string representation of a number at pos:
+ //
    if(pos < 0)
    {
       s.insert(0, 1, '1');
@@ -69,6 +78,9 @@
    }
    else
    {
+ //
+ // Start by figuring out the exponent:
+ //
       isneg = b.compare(ui_type(0)) < 0;
       if(isneg)
          b.negate();
@@ -96,10 +108,16 @@
       }
       Backend digit;
       ui_type cdigit;
+ //
+ // Adjust the number of digits required based on formatting options:
+ //
       if(((f & std::ios_base::fixed) == std::ios_base::fixed) && (expon != -1))
          digits += expon + 1;
       if((f & std::ios_base::scientific) == std::ios_base::scientific)
          ++digits;
+ //
+ // Extract the digits one at a time:
+ //
       for(unsigned i = 0; i < digits; ++i)
       {
          eval_floor(digit, t);
@@ -169,6 +187,9 @@
    bool is_neg_expon = false;
    static const ui_type ten = ui_type(10);
    typename Backend::exponent_type expon = 0;
+ int digits_seen = 0;
+ typedef std::numeric_limits<number<Backend, et_off> > limits;
+ static const int max_digits = limits::is_specialized ? limits::max_digits10 + 1 : INT_MAX;
 
    if(*p == '+') ++p;
    else if(*p == '-')
@@ -191,14 +212,22 @@
          b.negate();
       return;
    }
+ //
+ // Grab all the leading digits before the decimal point:
+ //
    while(std::isdigit(*p))
    {
       eval_multiply(b, ten);
       eval_add(b, ui_type(*p - '0'));
       ++p;
+ ++digits_seen;
    }
    if(*p == '.')
    {
+ //
+ // Grab everything after the point, stop when we've seen
+ // enough digits, even if there are actually more available:
+ //
       ++p;
       while(std::isdigit(*p))
       {
@@ -206,8 +235,15 @@
          eval_add(b, ui_type(*p - '0'));
          ++p;
          --expon;
+ if(++digits_seen > max_digits)
+ break;
       }
+ while(std::isdigit(*p))
+ ++p;
    }
+ //
+ // Parse the exponent:
+ //
    if((*p == 'e') || (*p == 'E'))
    {
       ++p;
@@ -230,11 +266,25 @@
    }
    if(expon)
    {
- // scale by 10^expon:
+ // Scale by 10^expon, note that 10^expon can be
+ // outside the range of our number type, even though the
+ // result is within range, if that looks likely, then split
+ // the calculation in two:
       Backend t;
       t = ten;
- eval_pow(t, t, expon);
- eval_multiply(b, t);
+ if(expon > limits::min_exponent10 + 2)
+ {
+ eval_pow(t, t, expon);
+ eval_multiply(b, t);
+ }
+ else
+ {
+ eval_pow(t, t, expon + digits_seen + 1);
+ eval_multiply(b, t);
+ t = ten;
+ eval_pow(t, t, -digits_seen - 1);
+ eval_multiply(b, t);
+ }
    }
    if(is_neg)
       b.negate();

Modified: trunk/libs/multiprecision/test/math/test_bessel_k.cpp
==============================================================================
--- trunk/libs/multiprecision/test/math/test_bessel_k.cpp (original)
+++ trunk/libs/multiprecision/test/math/test_bessel_k.cpp 2013-04-13 12:53:01 EDT (Sat, 13 Apr 2013)
@@ -27,7 +27,15 @@
       ".*gmp.*", // test type(s)
       ".*", // test data group
       ".*", 2000, 1500); // test function
-
+#ifdef BOOST_INTEL
+ add_expected_result(
+ ".*", // compiler
+ ".*", // stdlib
+ ".*", // platform
+ ".*float128.*", // test type(s)
+ ".*", // test data group
+ ".*", 300, 100); // test function
+#endif
    add_expected_result(
       ".*", // compiler
       ".*", // stdlib

Modified: trunk/libs/multiprecision/test/math/test_ellint_3.cpp
==============================================================================
--- trunk/libs/multiprecision/test/math/test_ellint_3.cpp (original)
+++ trunk/libs/multiprecision/test/math/test_ellint_3.cpp 2013-04-13 12:53:01 EDT (Sat, 13 Apr 2013)
@@ -37,6 +37,15 @@
       ".*", // test type(s)
       ".*Large.*", // test data group
       ".*", 75, 40); // test function
+#ifdef BOOST_INTEL
+ add_expected_result(
+ ".*", // compiler
+ ".*", // stdlib
+ ".*", // platform
+ ".*float128.*", // test type(s)
+ ".*", // test data group
+ ".*", 200, 30); // test function
+#endif
    add_expected_result(
       ".*", // compiler
       ".*", // stdlib

Modified: trunk/libs/multiprecision/test/math/test_erf.cpp
==============================================================================
--- trunk/libs/multiprecision/test/math/test_erf.cpp (original)
+++ trunk/libs/multiprecision/test/math/test_erf.cpp 2013-04-13 12:53:01 EDT (Sat, 13 Apr 2013)
@@ -30,6 +30,15 @@
       ".*gmp_float<18>.*", // test type(s)
       "Inverse Erf.*", // test data group
       "boost::math::erfc?_inv", 2200, 1500); // test function
+#ifdef BOOST_INTEL
+ add_expected_result(
+ ".*", // compiler
+ ".*", // stdlib
+ ".*", // platform
+ "float128", // test type(s)
+ "Erf Function:.*", // test data group
+ "boost::math::erfc?", 15000, 1000); // test function
+#endif
    add_expected_result(
       ".*", // compiler
       ".*", // stdlib

Modified: trunk/libs/multiprecision/test/math/test_expint.cpp
==============================================================================
--- trunk/libs/multiprecision/test/math/test_expint.cpp (original)
+++ trunk/libs/multiprecision/test/math/test_expint.cpp 2013-04-13 12:53:01 EDT (Sat, 13 Apr 2013)
@@ -37,6 +37,15 @@
       ".*gmp_float.*", // test type(s)
       ".*", // test data group
       ".*", 250, 100); // test function
+#ifdef BOOST_INTEL
+ add_expected_result(
+ ".*", // compiler
+ ".*", // stdlib
+ ".*", // platform
+ "float128", // test type(s)
+ ".*", // test data group
+ ".*", 4500, 1000); // test function
+#endif
    add_expected_result(
       ".*", // compiler
       ".*", // stdlib

Modified: trunk/libs/multiprecision/test/math/test_gamma.cpp
==============================================================================
--- trunk/libs/multiprecision/test/math/test_gamma.cpp (original)
+++ trunk/libs/multiprecision/test/math/test_gamma.cpp 2013-04-13 12:53:01 EDT (Sat, 13 Apr 2013)
@@ -37,6 +37,15 @@
       ".*", // test type(s)
       "factorials", // test data group
       "boost::math::lgamma", 750, 100); // test function
+#ifdef BOOST_INTEL
+ add_expected_result(
+ ".*", // compiler
+ ".*", // stdlib
+ ".*", // platform
+ "float128", // test type(s)
+ ".*near -.*", // test data group
+ ".*", 150000L, 30000L); // test function
+#endif
    add_expected_result(
       ".*", // compiler
       ".*", // stdlib

Modified: trunk/libs/multiprecision/test/math/test_hermite.cpp
==============================================================================
--- trunk/libs/multiprecision/test/math/test_hermite.cpp (original)
+++ trunk/libs/multiprecision/test/math/test_hermite.cpp 2013-04-13 12:53:01 EDT (Sat, 13 Apr 2013)
@@ -16,6 +16,15 @@
    // Define the max and mean errors expected for
    // various compilers and platforms.
    //
+#ifdef BOOST_INTEL
+ add_expected_result(
+ ".*", // compiler
+ ".*", // stdlib
+ ".*", // platform
+ "float128", // test type(s)
+ ".*", // test data group
+ "boost::math::hermite", 70, 25); // test function
+#endif
    add_expected_result(
       ".*", // compiler
       ".*", // stdlib

Modified: trunk/libs/multiprecision/test/math/test_ibeta.cpp
==============================================================================
--- trunk/libs/multiprecision/test/math/test_ibeta.cpp (original)
+++ trunk/libs/multiprecision/test/math/test_ibeta.cpp 2013-04-13 12:53:01 EDT (Sat, 13 Apr 2013)
@@ -32,6 +32,15 @@
       ".*mpfr_float_backend<18>.*", // test type(s)
       "(?i).*small.*", // test data group
       ".*", 2000, 500); // test function
+#ifdef BOOST_INTEL
+ add_expected_result(
+ "[^|]*", // compiler
+ "[^|]*", // stdlib
+ "[^|]*", // platform
+ "float128", // test type(s)
+ "(?i).*small.*", // test data group
+ ".*", 500, 100); // test function
+#endif
    add_expected_result(
       "[^|]*", // compiler
       "[^|]*", // stdlib

Modified: trunk/libs/multiprecision/test/math/test_ibeta_2.cpp
==============================================================================
--- trunk/libs/multiprecision/test/math/test_ibeta_2.cpp (original)
+++ trunk/libs/multiprecision/test/math/test_ibeta_2.cpp 2013-04-13 12:53:01 EDT (Sat, 13 Apr 2013)
@@ -39,6 +39,15 @@
       ".*", // test type(s)
       "(?i).*small.*", // test data group
       ".*", 90, 25); // test function
+#ifdef BOOST_INTEL
+ add_expected_result(
+ "[^|]*", // compiler
+ "[^|]*", // stdlib
+ "[^|]*", // platform
+ "float128", // test type(s)
+ "(?i).*medium.*", // test data group
+ ".*", 5000, 500); // test function
+#endif
    add_expected_result(
       "[^|]*", // compiler
       "[^|]*", // stdlib

Modified: trunk/libs/multiprecision/test/math/test_zeta.cpp
==============================================================================
--- trunk/libs/multiprecision/test/math/test_zeta.cpp (original)
+++ trunk/libs/multiprecision/test/math/test_zeta.cpp 2013-04-13 12:53:01 EDT (Sat, 13 Apr 2013)
@@ -23,6 +23,15 @@
       ".*", // test type(s)
       ".*Random values less than 1", // test data group
       ".*", 6000, 3000); // test function
+#ifdef BOOST_INTEL
+ add_expected_result(
+ ".*", // compiler
+ ".*", // stdlib
+ ".*", // platform
+ "float128", // test type(s)
+ ".*close to and less than 1.*", // test data group
+ ".*", 10000000L, 2000000L); // test function
+#endif
    add_expected_result(
       ".*", // compiler
       ".*", // stdlib

Modified: trunk/libs/multiprecision/test/test_cos.cpp
==============================================================================
--- trunk/libs/multiprecision/test/test_cos.cpp (original)
+++ trunk/libs/multiprecision/test/test_cos.cpp 2013-04-13 12:53:01 EDT (Sat, 13 Apr 2013)
@@ -252,7 +252,11 @@
          max_err = err;
    }
    std::cout << "Max error was: " << max_err << std::endl;
+#if defined(BOOST_INTEL) && defined(TEST_FLOAT128)
+ BOOST_TEST(max_err < 8000);
+#else
    BOOST_TEST(max_err < 750);
+#endif
 
    //
    // Test with some exact binary values as input - this tests our code
@@ -287,7 +291,11 @@
    BOOST_TEST(max_err < 20);
 
    BOOST_TEST(cos(T(0)) == 1);
+#if defined(BOOST_INTEL) && defined(TEST_FLOAT128)
+ BOOST_TEST(fabs(cos(half_pi)) < 4 * std::numeric_limits<T>::epsilon());
+#else
    BOOST_TEST(fabs(cos(half_pi)) < std::numeric_limits<T>::epsilon());
+#endif
 }
 
 

Modified: trunk/libs/multiprecision/test/test_exp.cpp
==============================================================================
--- trunk/libs/multiprecision/test/test_exp.cpp (original)
+++ trunk/libs/multiprecision/test/test_exp.cpp 2013-04-13 12:53:01 EDT (Sat, 13 Apr 2013)
@@ -134,7 +134,11 @@
       }
    }
    std::cout << "Max error was: " << max_err << std::endl;
+#if defined(BOOST_INTEL) && defined(TEST_FLOAT128)
+ BOOST_TEST(max_err < 40000);
+#else
    BOOST_TEST(max_err < 5000);
+#endif
 
    static const boost::array<boost::array<T, 2>, 10> exact_data =
    {{

Modified: trunk/libs/multiprecision/test/test_float_io.cpp
==============================================================================
--- trunk/libs/multiprecision/test/test_float_io.cpp (original)
+++ trunk/libs/multiprecision/test/test_float_io.cpp 2013-04-13 12:53:01 EDT (Sat, 13 Apr 2013)
@@ -55,11 +55,15 @@
 
 #if defined(TEST_MPF_50)
 template <unsigned N, boost::multiprecision::expression_template_option ET>
-bool is_mpf(const boost::multiprecision::number<boost::multiprecision::gmp_float<N>, ET>&)
+bool has_bad_bankers_rounding(const boost::multiprecision::number<boost::multiprecision::gmp_float<N>, ET>&)
+{ return true; }
+#endif
+#if defined(TEST_FLOAT128) && defined(BOOST_INTEL)
+bool has_bad_bankers_rounding(const boost::multiprecision::float128&)
 { return true; }
 #endif
 template <class T>
-bool is_mpf(const T&) { return false; }
+bool has_bad_bankers_rounding(const T&) { return false; }
 
 bool is_bankers_rounding_error(const std::string& s, const char* expect)
 {
@@ -126,7 +130,7 @@
             const char* expect = string_data[j][col];
             if(ss.str() != expect)
             {
- if(is_mpf(mp_t()) && is_bankers_rounding_error(ss.str(), expect))
+ if(has_bad_bankers_rounding(mp_t()) && is_bankers_rounding_error(ss.str(), expect))
                {
                   std::cout << "Ignoring bankers-rounding error with GMP mp_f.\n";
                }

Modified: trunk/libs/multiprecision/test/test_log.cpp
==============================================================================
--- trunk/libs/multiprecision/test/test_log.cpp (original)
+++ trunk/libs/multiprecision/test/test_log.cpp 2013-04-13 12:53:01 EDT (Sat, 13 Apr 2013)
@@ -196,7 +196,11 @@
          max_err = err;
    }
    std::cout << "Max error was: " << max_err << std::endl;
+#if defined(BOOST_INTEL) && defined(TEST_FLOAT128)
+ BOOST_TEST(max_err < 20);
+#else
    BOOST_TEST(max_err < 10);
+#endif
    BOOST_TEST(log(T(1)) == 0);
 }
 

Modified: trunk/libs/multiprecision/test/test_sqrt.cpp
==============================================================================
--- trunk/libs/multiprecision/test/test_sqrt.cpp (original)
+++ trunk/libs/multiprecision/test/test_sqrt.cpp 2013-04-13 12:53:01 EDT (Sat, 13 Apr 2013)
@@ -174,7 +174,11 @@
       }
    }
    std::cout << "Max error was: " << max_err << std::endl;
+#if defined(BOOST_INTEL) && defined(TEST_FLOAT128)
+ BOOST_TEST(max_err < 30);
+#else
    BOOST_TEST(max_err < 20);
+#endif
 }
 
 


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