1 // Copyright John Maddock 2011.
3 // Use, modification and distribution are subject to the
4 // Boost Software License, Version 1.0.
5 // (See accompanying file LICENSE_1_0.txt
6 // or copy at http://www.boost.org/LICENSE_1_0.txt)
9 # define _SCL_SECURE_NO_WARNINGS
12 #if !defined(TEST_MPZ) && !defined(TEST_TOMMATH) && !defined(TEST_CPP_INT)
18 #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!")
21 #pragma warning "CAUTION!!: No backend type specified so testing everything.... this will take some time!!"
27 #include <boost/multiprecision/gmp.hpp>
29 #if defined(TEST_TOMMATH)
30 #include <boost/multiprecision/tommath.hpp>
33 #include <boost/multiprecision/cpp_int.hpp>
36 #include <boost/algorithm/string/case_conv.hpp>
37 #include <boost/random/mersenne_twister.hpp>
38 #include <boost/random/uniform_int.hpp>
44 #pragma warning(disable:4127)
48 struct unchecked_type
{ typedef T type
; };
51 template <unsigned MinBits
, unsigned MaxBits
, boost::multiprecision::cpp_integer_type SignType
, boost::multiprecision::cpp_int_check_type Checked
, class Allocator
, boost::multiprecision::expression_template_option ExpressionTemplates
>
52 struct unchecked_type
<boost::multiprecision::number
<boost::multiprecision::cpp_int_backend
<MinBits
, MaxBits
, SignType
, Checked
, Allocator
>, ExpressionTemplates
> >
54 typedef boost::multiprecision::number
<boost::multiprecision::cpp_int_backend
<MinBits
, MaxBits
, SignType
, boost::multiprecision::unchecked
, Allocator
>, ExpressionTemplates
> type
;
61 typedef typename unchecked_type
<T
>::type unchecked_T
;
63 static const unsigned limbs
= std::numeric_limits
<T
>::is_specialized
&& std::numeric_limits
<T
>::is_bounded
? std::numeric_limits
<T
>::digits
/ std::numeric_limits
<unsigned>::digits
+ 3 : 20;
65 static boost::random::uniform_int_distribution
<unsigned> ui(0, limbs
);
66 static boost::random::mt19937 gen
;
67 unchecked_T val
= gen();
68 unsigned lim
= ui(gen
);
69 for(unsigned i
= 0; i
< lim
; ++i
)
78 void do_round_trip(const T
& val
, std::ios_base::fmtflags f
)
81 #ifndef BOOST_NO_CXX11_NUMERIC_LIMITS
82 ss
<< std::setprecision(std::numeric_limits
<T
>::max_digits10
);
84 ss
<< std::setprecision(std::numeric_limits
<T
>::digits10
+ 5);
88 T new_val
= static_cast<T
>(ss
.str());
89 BOOST_CHECK_EQUAL(new_val
, val
);
90 new_val
= static_cast<T
>(val
.str(0, f
));
91 BOOST_CHECK_EQUAL(new_val
, val
);
93 BOOST_CHECK_EQUAL(new_val
, val
);
97 void do_round_trip(const T
& val
)
99 do_round_trip(val
, std::ios_base::fmtflags(0));
102 do_round_trip(val
, std::ios_base::fmtflags(std::ios_base::showbase
|std::ios_base::hex
));
103 do_round_trip(val
, std::ios_base::fmtflags(std::ios_base::showbase
|std::ios_base::oct
));
108 void negative_round_trip(T val
, const boost::mpl::true_
&)
110 do_round_trip(T(-val
));
113 void negative_round_trip(T
, const boost::mpl::false_
&)
118 void negative_spots(const boost::mpl::true_
&)
120 BOOST_CHECK_EQUAL(T(-1002).str(), "-1002");
121 if(!std::numeric_limits
<T
>::is_modulo
)
123 #ifndef BOOST_NO_EXCEPTIONS
124 BOOST_CHECK_THROW(T(-2).str(0, std::ios_base::oct
), std::runtime_error
);
125 BOOST_CHECK_THROW(T(-2).str(0, std::ios_base::hex
), std::runtime_error
);
130 void negative_spots(const boost::mpl::false_
&)
135 void test_round_trip()
137 for(unsigned i
= 0; i
< 1000; ++i
)
139 T val
= generate_random
<T
>();
141 negative_round_trip(val
, boost::mpl::bool_
<std::numeric_limits
<T
>::is_signed
>());
144 BOOST_CHECK_EQUAL(T(1002).str(), "1002");
145 BOOST_CHECK_EQUAL(T(1002).str(0, std::ios_base::showpos
), "+1002");
146 BOOST_CHECK_EQUAL(T(1002).str(0, std::ios_base::oct
), "1752");
147 BOOST_CHECK_EQUAL(T(1002).str(0, std::ios_base::oct
|std::ios_base::showbase
), "01752");
148 BOOST_CHECK_EQUAL(boost::to_lower_copy(T(1002).str(0, std::ios_base::hex
)), "3ea");
149 BOOST_CHECK_EQUAL(boost::to_lower_copy(T(1002).str(0, std::ios_base::hex
|std::ios_base::showbase
)), "0x3ea");
150 BOOST_CHECK_EQUAL(T(1002).str(0, std::ios_base::dec
), "1002");
151 BOOST_CHECK_EQUAL(T(1002).str(0, std::ios_base::dec
|std::ios_base::showbase
), "1002");
153 negative_spots
<T
>(boost::mpl::bool_
<std::numeric_limits
<T
>::is_signed
>());
159 test_round_trip
<boost::multiprecision::mpz_int
>();
162 test_round_trip
<boost::multiprecision::tom_int
>();
165 test_round_trip
<boost::multiprecision::cpp_int
>();
166 test_round_trip
<boost::multiprecision::checked_int1024_t
>();
167 test_round_trip
<boost::multiprecision::checked_uint512_t
>();
168 test_round_trip
<boost::multiprecision::number
<boost::multiprecision::cpp_int_backend
<32, 32, boost::multiprecision::signed_magnitude
, boost::multiprecision::checked
, void> > >();
169 test_round_trip
<boost::multiprecision::number
<boost::multiprecision::cpp_int_backend
<32, 32, boost::multiprecision::unsigned_magnitude
, boost::multiprecision::checked
, void> > >();
171 return boost::report_errors();