Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r76121 - in sandbox/big_number: boost/multiprecision libs/multiprecision/test
From: john_at_[hidden]
Date: 2011-12-23 12:13:31


Author: johnmaddock
Date: 2011-12-23 12:13:29 EST (Fri, 23 Dec 2011)
New Revision: 76121
URL: http://svn.boost.org/trac/boost/changeset/76121

Log:
Fix remaining Boost.Rational support issues and add rational number IO test.
Added:
   sandbox/big_number/libs/multiprecision/test/test_rational_io.cpp (contents, props changed)
Text files modified:
   sandbox/big_number/boost/multiprecision/mp_number.hpp | 42 +++++++
   sandbox/big_number/libs/multiprecision/test/Jamfile.v2 | 228 +++++++++++++++++++++++----------------
   sandbox/big_number/libs/multiprecision/test/test_arithmetic.cpp | 49 +++++++-
   sandbox/big_number/libs/multiprecision/test/test_float_io.cpp | 2
   4 files changed, 219 insertions(+), 102 deletions(-)

Modified: sandbox/big_number/boost/multiprecision/mp_number.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/mp_number.hpp (original)
+++ sandbox/big_number/boost/multiprecision/mp_number.hpp 2011-12-23 12:13:29 EST (Fri, 23 Dec 2011)
@@ -1571,6 +1571,46 @@
    a.swap(b);
 }
 
-}} // namespaces
+} // namespace multipreciion
+
+template <class T>
+class rational;
+
+template <class Backend>
+inline std::istream& operator >> (std::istream& is, rational<multiprecision::mp_number<Backend> >& r)
+{
+ std::string s1;
+ multiprecision::mp_number<Backend> v1, v2;
+ char c;
+ bool have_hex = false;
+
+ while((EOF != (c = is.peek())) && (c == 'x' || c == 'X' || c == '-' || c == '+' || (c >= '0' && c <= '9') || (have_hex && (c >= 'a' && c <= 'f')) || (have_hex && (c >= 'A' && c <= 'F'))))
+ {
+ if(c == 'x' || c == 'X')
+ have_hex = true;
+ s1.append(1, c);
+ is.get();
+ }
+ v1 = s1;
+ s1.erase();
+ if(c == '/')
+ {
+ is.get();
+ while((EOF != (c = is.peek())) && (c == 'x' || c == 'X' || c == '-' || c == '+' || (c >= '0' && c <= '9') || (have_hex && (c >= 'a' && c <= 'f')) || (have_hex && (c >= 'A' && c <= 'F'))))
+ {
+ if(c == 'x' || c == 'X')
+ have_hex = true;
+ s1.append(1, c);
+ is.get();
+ }
+ v2 = s1;
+ }
+ else
+ v2 = 1;
+ r.assign(v1, v2);
+ return is;
+}
+
+} // namespaces
 
 #endif

Modified: sandbox/big_number/libs/multiprecision/test/Jamfile.v2
==============================================================================
--- sandbox/big_number/libs/multiprecision/test/Jamfile.v2 (original)
+++ sandbox/big_number/libs/multiprecision/test/Jamfile.v2 2011-12-23 12:13:29 EST (Fri, 23 Dec 2011)
@@ -25,6 +25,10 @@
    <toolset>msvc:<runtime-link>static
    ;
 
+local disable-specfun = [ MATCH (--disable-specfun) : [ modules.peek : ARGV ] ] ;
+local disable-concepts = [ MATCH (--disable-concepts) : [ modules.peek : ARGV ] ] ;
+
+
 lib gmp ;
 lib mpfr ;
 
@@ -80,6 +84,14 @@
         : # command line
         : # input files
         : # requirements
+ <define>TEST_MPZ_BOOST_RATIONAL
+ [ check-target-builds ../config//has_gmp : : <build>no ]
+ : test_arithmetic_mpz_br ;
+
+run test_arithmetic.cpp gmp
+ : # command line
+ : # input files
+ : # requirements
               <define>TEST_MPQ
          [ check-target-builds ../config//has_gmp : : <build>no ]
         : test_arithmetic_mpq ;
@@ -108,6 +120,14 @@
          [ check-target-builds ../config//has_tommath : : <build>no ]
         : test_arithmetic_tommath ;
 
+run test_arithmetic.cpp $(TOMMATH)
+ : # command line
+ : # input files
+ : # requirements
+ <define>TEST_TOMMATH_BOOST_RATIONAL
+ [ check-target-builds ../config//has_tommath : : <build>no ]
+ : test_arithmetic_tommath_br ;
+
 run test_numeric_limits.cpp
         : # command line
         : # input files
@@ -179,68 +199,6 @@
          [ check-target-builds ../config//has_tommath : : <build>no ]
         : test_numeric_limits_tommath ;
 
-run mp_number_concept_check.cpp mpfr
- : # command line
- : # input files
- : # requirements
- <define>TEST_MPFR_50
- [ check-target-builds ../config//has_mpfr : : <build>no ]
- : mp_number_concept_check_mpfr_50 ;
-
-run mp_number_concept_check.cpp mpfr
- : # command line
- : # input files
- : # requirements
- <define>TEST_MPFR_6
- [ check-target-builds ../config//has_mpfr : : <build>no ]
- : mp_number_concept_check_mpfr_6 ;
-
-run mp_number_concept_check.cpp mpfr
- : # command line
- : # input files
- : # requirements
- <define>TEST_MPFR_15
- [ check-target-builds ../config//has_mpfr : : <build>no ]
- : mp_number_concept_check_mpfr_15 ;
-
-run mp_number_concept_check.cpp mpfr
- : # command line
- : # input files
- : # requirements
- <define>TEST_MPFR_17
- [ check-target-builds ../config//has_mpfr : : <build>no ]
- : mp_number_concept_check_mpfr_17 ;
-
-run mp_number_concept_check.cpp mpfr
- : # command line
- : # input files
- : # requirements
- <define>TEST_MPFR_30
- [ check-target-builds ../config//has_mpfr : : <build>no ]
- : mp_number_concept_check_mpfr_30 ;
-
-run mp_number_concept_check.cpp gmp
- : # command line
- : # input files
- : # requirements
- <define>TEST_MPF_50
- [ check-target-builds ../config//has_gmp : : <build>no ]
- : mp_number_concept_check_mpf50 ;
-
-run mp_number_concept_check.cpp
- : # command line
- : # input files
- : # requirements
- <define>TEST_CPP_FLOAT
- : mp_number_concept_check_cpp_float ;
-
-run mp_number_concept_check.cpp
- : # command line
- : # input files
- : # requirements
- <define>TEST_BACKEND
- : mp_number_concept_check_backend_concept ;
-
 run test_exp.cpp gmp
         : # command line
         : # input files
@@ -609,6 +567,22 @@
          [ check-target-builds ../config//has_gmp : : <build>no ]
         : test_int_io_mpz ;
 
+run test_rational_io.cpp $(TOMMATH)
+ : # command line
+ : # input files
+ : # requirements
+ <define>TEST_TOMMATH
+ [ check-target-builds ../config//has_tommath : : <build>no ]
+ : test_rational_io_tommath ;
+
+run test_rational_io.cpp gmp
+ : # command line
+ : # input files
+ : # requirements
+ <define>TEST_MPQ
+ [ check-target-builds ../config//has_gmp : : <build>no ]
+ : test_rational_io_mpz ;
+
 run ../example/gmp_snips.cpp gmp
         : # command line
         : # input files
@@ -630,35 +604,105 @@
          [ check-target-builds ../config//has_tommath : : <build>no ] ;
 
 
-for local source in [ glob math/*.cpp ]
+if ! $(disable-specfun)
 {
- run $(source) mpfr gmp /boost/test//boost_test_exec_monitor/<link>static /boost/regex//boost_regex/<link>static
- : # command line
- : # input files
- : # requirements
- [ check-target-builds ../config//has_mpfr : : <build>no ]
- <define>TEST_MPFR_50
- <optimization>speed
- <define>BOOST_ALL_NO_LIB
- <toolset>msvc:<cxxflags>-bigobj
- : $(source:B)_mpfr ;
- run $(source) gmp /boost/test//boost_test_exec_monitor/<link>static /boost/regex//boost_regex/<link>static
- : # command line
- : # input files
- : # requirements
- [ check-target-builds ../config//has_gmp : : <build>no ]
- <optimization>speed
- <define>TEST_MPF_50
- <define>BOOST_ALL_NO_LIB
- <toolset>msvc:<cxxflags>-bigobj
- : $(source:B)_mpf ;
- run $(source) /boost/test//boost_test_exec_monitor/<link>static /boost/regex//boost_regex/<link>static
- : # command line
- : # input files
- : # requirements
- <define>TEST_CPP_FLOAT
- <define>BOOST_ALL_NO_LIB
- <optimization>speed
- <toolset>msvc:<cxxflags>-bigobj
- : $(source:B)_cpp_float ;
+
+ for local source in [ glob math/*.cpp ]
+ {
+ run $(source) mpfr gmp /boost/test//boost_test_exec_monitor/<link>static /boost/regex//boost_regex/<link>static
+ : # command line
+ : # input files
+ : # requirements
+ [ check-target-builds ../config//has_mpfr : : <build>no ]
+ <define>TEST_MPFR_50
+ <optimization>speed
+ <define>BOOST_ALL_NO_LIB
+ <toolset>msvc:<cxxflags>-bigobj
+ : $(source:B)_mpfr ;
+ run $(source) gmp /boost/test//boost_test_exec_monitor/<link>static /boost/regex//boost_regex/<link>static
+ : # command line
+ : # input files
+ : # requirements
+ [ check-target-builds ../config//has_gmp : : <build>no ]
+ <optimization>speed
+ <define>TEST_MPF_50
+ <define>BOOST_ALL_NO_LIB
+ <toolset>msvc:<cxxflags>-bigobj
+ : $(source:B)_mpf ;
+ run $(source) /boost/test//boost_test_exec_monitor/<link>static /boost/regex//boost_regex/<link>static
+ : # command line
+ : # input files
+ : # requirements
+ <define>TEST_CPP_FLOAT
+ <define>BOOST_ALL_NO_LIB
+ <optimization>speed
+ <toolset>msvc:<cxxflags>-bigobj
+ : $(source:B)_cpp_float ;
+ }
+}
+
+if ! $(disable-concepts)
+{
+ run mp_number_concept_check.cpp mpfr
+ : # command line
+ : # input files
+ : # requirements
+ <define>TEST_MPFR_50
+ [ check-target-builds ../config//has_mpfr : : <build>no ]
+ : mp_number_concept_check_mpfr_50 ;
+
+ run mp_number_concept_check.cpp mpfr
+ : # command line
+ : # input files
+ : # requirements
+ <define>TEST_MPFR_6
+ [ check-target-builds ../config//has_mpfr : : <build>no ]
+ : mp_number_concept_check_mpfr_6 ;
+
+ run mp_number_concept_check.cpp mpfr
+ : # command line
+ : # input files
+ : # requirements
+ <define>TEST_MPFR_15
+ [ check-target-builds ../config//has_mpfr : : <build>no ]
+ : mp_number_concept_check_mpfr_15 ;
+
+ run mp_number_concept_check.cpp mpfr
+ : # command line
+ : # input files
+ : # requirements
+ <define>TEST_MPFR_17
+ [ check-target-builds ../config//has_mpfr : : <build>no ]
+ : mp_number_concept_check_mpfr_17 ;
+
+ run mp_number_concept_check.cpp mpfr
+ : # command line
+ : # input files
+ : # requirements
+ <define>TEST_MPFR_30
+ [ check-target-builds ../config//has_mpfr : : <build>no ]
+ : mp_number_concept_check_mpfr_30 ;
+
+ run mp_number_concept_check.cpp gmp
+ : # command line
+ : # input files
+ : # requirements
+ <define>TEST_MPF_50
+ [ check-target-builds ../config//has_gmp : : <build>no ]
+ : mp_number_concept_check_mpf50 ;
+
+ run mp_number_concept_check.cpp
+ : # command line
+ : # input files
+ : # requirements
+ <define>TEST_CPP_FLOAT
+ : mp_number_concept_check_cpp_float ;
+
+ run mp_number_concept_check.cpp
+ : # command line
+ : # input files
+ : # requirements
+ <define>TEST_BACKEND
+ : mp_number_concept_check_backend_concept ;
+
 }

Modified: sandbox/big_number/libs/multiprecision/test/test_arithmetic.cpp
==============================================================================
--- sandbox/big_number/libs/multiprecision/test/test_arithmetic.cpp (original)
+++ sandbox/big_number/libs/multiprecision/test/test_arithmetic.cpp 2011-12-23 12:13:29 EST (Fri, 23 Dec 2011)
@@ -10,7 +10,9 @@
 #include <boost/detail/lightweight_test.hpp>
 #include <boost/math/special_functions/pow.hpp>
 
-#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) && !defined(TEST_TOMMATH)
+#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && \
+ !defined(TEST_CPP_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) \
+ && !defined(TEST_TOMMATH) && !defined(TEST_TOMMATH_BOOST_RATIONAL) && !defined(TEST_MPZ_BOOST_RATIONAL)
 # define TEST_MPF_50
 # define TEST_MPF
 # define TEST_BACKEND
@@ -30,7 +32,7 @@
 
 #endif
 
-#if defined(TEST_MPF_50) || defined(TEST_MPF) || defined(TEST_MPZ) || defined(TEST_MPQ)
+#if defined(TEST_MPF_50) || defined(TEST_MPF) || defined(TEST_MPZ) || defined(TEST_MPQ) || defined(TEST_MPZ_BOOST_RATIONAL)
 #include <boost/multiprecision/gmp.hpp>
 #endif
 #ifdef TEST_BACKEND
@@ -42,9 +44,28 @@
 #if defined(TEST_MPFR) || defined(TEST_MPFR_50)
 #include <boost/multiprecision/mpfr.hpp>
 #endif
-#ifdef TEST_TOMMATH
+#if defined(TEST_TOMMATH) || defined(TEST_TOMMATH_BOOST_RATIONAL)
 #include <boost/multiprecision/tommath.hpp>
 #endif
+#if defined(TEST_TOMMATH_BOOST_RATIONAL) || defined(TEST_MPZ_BOOST_RATIONAL)
+#include <boost/rational.hpp>
+
+#define NO_MIXED_OPS
+
+namespace boost{ namespace multiprecision{
+
+#ifdef TEST_TOMMATH_BOOST_RATIONAL
+template<>
+struct number_category<rational<mp_int> > : public mpl::int_<number_kind_rational> {};
+#endif
+#ifdef TEST_MPZ_BOOST_RATIONAL
+template<>
+struct number_category<rational<mpz_int> > : public mpl::int_<number_kind_rational> {};
+#endif
+
+}}
+
+#endif
 
 #define BOOST_TEST_THROW(x, EX)\
    try { x; BOOST_ERROR("Expected exception not thrown"); } \
@@ -637,7 +658,9 @@
    BOOST_TEST(ac == 64 * 2);
    ac = a;
    ac = b - ac * a;
+#ifndef NO_MIXED_OPS
    BOOST_TEST(ac == 0);
+#endif
    ac = a;
    ac = b * (ac + a);
    BOOST_TEST(ac == 64 * (16));
@@ -655,7 +678,9 @@
    BOOST_TEST(ac == 8 - 64);
    ac = a;
    ac = a - ac;
+#ifndef NO_MIXED_OPS
    BOOST_TEST(ac == 0);
+#endif
    ac = a;
    ac += a + b;
    BOOST_TEST(ac == 80);
@@ -681,7 +706,9 @@
    BOOST_TEST(ac == 16);
    ac = a;
    ac += -a;
+#ifndef NO_MIXED_OPS
    BOOST_TEST(ac == 0);
+#endif
    ac = a;
    ac += b - a;
    BOOST_TEST(ac == 8 + 64-8);
@@ -691,7 +718,9 @@
    ac = a;
    ac = a;
    ac -= +a;
+#ifndef NO_MIXED_OPS
    BOOST_TEST(ac == 0);
+#endif
    ac = a;
    ac -= -a;
    BOOST_TEST(ac == 16);
@@ -805,6 +834,7 @@
    BOOST_TEST((72 < b+a) == false);
    BOOST_TEST((72 >= b+a) == true);
    BOOST_TEST((72 > b+a) == false);
+#ifndef NO_MIXED_OPS
    //
    // Test sign and zero functions, plus use in boolian context:
    //
@@ -817,6 +847,8 @@
    a = 0;
    BOOST_TEST(a.sign() == 0);
    BOOST_TEST(a.is_zero());
+#endif
+ a = 0;
    if(a)
    {
       BOOST_ERROR("Unexpected non-zero result");
@@ -880,11 +912,6 @@
 #endif
 #ifdef TEST_MPF
    boost::multiprecision::mpf_float::default_precision(1000);
- /*
- boost::multiprecision::mpf_float r;
- r.precision(50);
- BOOST_TEST(r.precision() >= 50);
- */
    BOOST_TEST(boost::multiprecision::mpf_float::default_precision() == 1000);
    test<boost::multiprecision::mpf_float>();
 #endif
@@ -906,6 +933,12 @@
 #ifdef TEST_TOMMATH
    test<boost::multiprecision::mp_int>();
 #endif
+#ifdef TEST_TOMMATH_BOOST_RATIONAL
+ test<boost::rational<boost::multiprecision::mp_int> >();
+#endif
+#ifdef TEST_MPZ_BOOST_RATIONAL
+ test<boost::rational<boost::multiprecision::mpz_int> >();
+#endif
    return boost::report_errors();
 }
 

Modified: sandbox/big_number/libs/multiprecision/test/test_float_io.cpp
==============================================================================
--- sandbox/big_number/libs/multiprecision/test/test_float_io.cpp (original)
+++ sandbox/big_number/libs/multiprecision/test/test_float_io.cpp 2011-12-23 12:13:29 EST (Fri, 23 Dec 2011)
@@ -50,7 +50,7 @@
 
 bool is_bankers_rounding_error(const std::string& s, const char* expect)
 {
- // This check isn't foolproof: that would require *much* more sofisticated code!!!
+ // This check isn't foolproof: that would require *much* more sophisticated code!!!
    std::string::size_type l = std::strlen(expect);
    if(l != s.size())
       return false;

Added: sandbox/big_number/libs/multiprecision/test/test_rational_io.cpp
==============================================================================
--- (empty file)
+++ sandbox/big_number/libs/multiprecision/test/test_rational_io.cpp 2011-12-23 12:13:29 EST (Fri, 23 Dec 2011)
@@ -0,0 +1,131 @@
+// Copyright John Maddock 2011.
+
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifdef _MSC_VER
+# define _SCL_SECURE_NO_WARNINGS
+#endif
+
+#if !defined(TEST_MPQ) && !defined(TEST_TOMMATH)
+# define TEST_MPQ
+# define TEST_TOMMATH
+
+#ifdef _MSC_VER
+#pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!")
+#endif
+#ifdef __GNUC__
+#pragma warning "CAUTION!!: No backend type specified so testing everything.... this will take some time!!"
+#endif
+
+#endif
+
+#if defined(TEST_MPQ)
+#include <boost/multiprecision/gmp.hpp>
+#endif
+#if defined(TEST_TOMMATH)
+#include <boost/multiprecision/tommath.hpp>
+#endif
+
+#include <boost/algorithm/string/case_conv.hpp>
+#include <boost/random/mersenne_twister.hpp>
+#include <boost/random/uniform_int.hpp>
+#include <boost/rational.hpp>
+#include "test.hpp"
+#include <iostream>
+#include <iomanip>
+
+template <class T>
+T generate_random()
+{
+ static boost::random::uniform_int_distribution<unsigned> ui(0, 20);
+ static boost::random::mt19937 gen;
+ T val = gen();
+ unsigned lim = ui(gen);
+ for(unsigned i = 0; i < lim; ++i)
+ {
+ val *= (gen.max)();
+ val += gen();
+ }
+ T denom = gen();
+ lim = ui(gen);
+ for(unsigned i = 0; i < lim; ++i)
+ {
+ denom *= (gen.max)();
+ denom += gen();
+ }
+ return val / denom;
+}
+
+template <class T>
+void do_round_trip(const T& val, std::ios_base::fmtflags f, const boost::mpl::true_&)
+{
+ std::stringstream ss;
+ ss << std::setprecision(std::numeric_limits<T>::max_digits10);
+ ss.flags(f);
+ ss << val;
+ T new_val = ss.str();
+ BOOST_CHECK_EQUAL(new_val, val);
+ new_val = val.str(0, f);
+ BOOST_CHECK_EQUAL(new_val, val);
+}
+
+template <class T>
+void do_round_trip(const T& val, std::ios_base::fmtflags f, const boost::mpl::false_&)
+{
+ std::stringstream ss;
+ ss << std::setprecision(std::numeric_limits<T>::max_digits10);
+ ss.flags(f);
+ ss << val;
+ T new_val;
+ ss >> new_val;
+ BOOST_CHECK_EQUAL(new_val, val);
+}
+
+template <class T>
+struct is_mp_number : public boost::mpl::false_{};
+template <class T>
+struct is_mp_number<boost::multiprecision::mp_number<T> > : public boost::mpl::true_{};
+
+template <class T>
+void do_round_trip(const T& val, std::ios_base::fmtflags f)
+{
+ do_round_trip(val, f, is_mp_number<T>());
+}
+
+template <class T>
+void do_round_trip(const T& val)
+{
+ do_round_trip(val, std::ios_base::fmtflags(0));
+ if(val >= 0)
+ {
+ do_round_trip(val, std::ios_base::fmtflags(std::ios_base::showbase|std::ios_base::hex));
+ do_round_trip(val, std::ios_base::fmtflags(std::ios_base::showbase|std::ios_base::oct));
+ }
+}
+
+template <class T>
+void test_round_trip()
+{
+ for(unsigned i = 0; i < 1000; ++i)
+ {
+ T val = generate_random<T>();
+ do_round_trip(val);
+ do_round_trip(T(-val));
+ }
+}
+
+int main()
+{
+#ifdef TEST_MPQ
+ test_round_trip<boost::multiprecision::mpq_rational>();
+ test_round_trip<boost::rational<boost::multiprecision::mpz_int> >();
+#endif
+#ifdef TEST_TOMMATH
+ test_round_trip<boost::rational<boost::multiprecision::mp_int> >();
+#endif
+ return boost::report_errors();
+}
+


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