1 ///////////////////////////////////////////////////////////////
2 // Copyright 2012 John Maddock. Distributed under the Boost
3 // Software License, Version 1.0. (See accompanying file
4 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_
7 # define _SCL_SECURE_NO_WARNINGS
10 #include <boost/multiprecision/cpp_int.hpp>
11 #include <boost/random/mersenne_twister.hpp>
15 #include <boost/multiprecision/gmp.hpp>
18 #include <boost/multiprecision/mpfr.hpp>
21 #include <boost/multiprecision/mpfi.hpp>
24 #include <boost/multiprecision/tommath.hpp>
27 #include <boost/multiprecision/float128.hpp>
29 #include <boost/multiprecision/cpp_bin_float.hpp>
30 #include <boost/multiprecision/cpp_dec_float.hpp>
33 using namespace boost::multiprecision
;
36 #pragma warning(disable:4127)
41 T
generate_random(unsigned bits_wanted
)
43 static boost::random::mt19937 gen
;
44 typedef boost::random::mt19937::result_type random_type
;
48 if(std::numeric_limits
<T
>::is_bounded
&& (bits_wanted
== (unsigned)std::numeric_limits
<T
>::digits
))
50 max_val
= (std::numeric_limits
<T
>::max
)();
51 digits
= std::numeric_limits
<T
>::digits
;
55 max_val
= T(1) << bits_wanted
;
59 unsigned bits_per_r_val
= std::numeric_limits
<random_type
>::digits
- 1;
60 while((random_type(1) << bits_per_r_val
) > (gen
.max
)()) --bits_per_r_val
;
62 unsigned terms_needed
= digits
/ bits_per_r_val
+ 1;
65 for(unsigned i
= 0; i
< terms_needed
; ++i
)
74 template <class From
, class To
>
75 void test_convert_neg_int(From from
, const boost::mpl::true_
&)
79 To t4
= from
.template convert_to
<To
>();
80 BOOST_CHECK_EQUAL(from
.str(), t3
.str());
81 BOOST_CHECK_EQUAL(from
.str(), t4
.str());
83 template <class From
, class To
>
84 void test_convert_neg_int(From
const&, const boost::mpl::false_
&)
88 template <class From
, class To
>
89 void test_convert_imp(boost::mpl::int_
<number_kind_integer
> const&, boost::mpl::int_
<number_kind_integer
> const&)
91 int bits_wanted
= (std::min
)((std::min
)(std::numeric_limits
<From
>::digits
, std::numeric_limits
<To
>::digits
), 2000);
93 for(unsigned i
= 0; i
< 100; ++i
)
95 From from
= generate_random
<From
>(bits_wanted
);
97 To t2
= from
.template convert_to
<To
>();
98 BOOST_CHECK_EQUAL(from
.str(), t1
.str());
99 BOOST_CHECK_EQUAL(from
.str(), t2
.str());
100 test_convert_neg_int
<From
, To
>(from
, boost::mpl::bool_
<std::numeric_limits
<From
>::is_signed
&& std::numeric_limits
<To
>::is_signed
>());
104 template <class From
, class To
>
105 void test_convert_neg_rat(From from
, const boost::mpl::true_
&)
109 To t4
= from
.template convert_to
<To
>();
110 BOOST_CHECK_EQUAL(from
.str(), numerator(t3
).str());
111 BOOST_CHECK_EQUAL(from
.str(), numerator(t4
).str());
113 template <class From
, class To
>
114 void test_convert_neg_rat(From
const&, const boost::mpl::false_
&)
118 template <class From
, class To
>
119 void test_convert_imp(boost::mpl::int_
<number_kind_integer
> const&, boost::mpl::int_
<number_kind_rational
> const&)
121 int bits_wanted
= (std::min
)((std::min
)(std::numeric_limits
<From
>::digits
, std::numeric_limits
<To
>::digits
), 2000);
123 for(unsigned i
= 0; i
< 100; ++i
)
125 From from
= generate_random
<From
>(bits_wanted
);
127 To t2
= from
.template convert_to
<To
>();
128 BOOST_CHECK_EQUAL(from
.str(), numerator(t1
).str());
129 BOOST_CHECK_EQUAL(from
.str(), numerator(t2
).str());
130 test_convert_neg_rat
<From
, To
>(from
, boost::mpl::bool_
<std::numeric_limits
<From
>::is_signed
&& std::numeric_limits
<To
>::is_signed
>());
134 template <class From
, class To
>
135 void test_convert_neg_float(From from
, const boost::mpl::true_
&)
139 To t4
= from
.template convert_to
<To
>();
140 To
check(from
.str() + ".0");
141 BOOST_CHECK_EQUAL(t3
, check
);
142 BOOST_CHECK_EQUAL(t4
, check
);
144 template <class From
, class To
>
145 void test_convert_neg_float(From
const&, const boost::mpl::false_
&)
149 template <class From
, class To
>
150 void test_convert_imp(boost::mpl::int_
<number_kind_integer
> const&, boost::mpl::int_
<number_kind_floating_point
> const&)
152 int bits_wanted
= (std::min
)((std::min
)(std::numeric_limits
<From
>::digits
, std::numeric_limits
<To
>::digits
), 2000);
154 for(unsigned i
= 0; i
< 100; ++i
)
156 From from
= generate_random
<From
>(bits_wanted
);
158 To t2
= from
.template convert_to
<To
>();
159 To
check(from
.str() + ".0");
160 BOOST_CHECK_EQUAL(t1
, check
);
161 BOOST_CHECK_EQUAL(t2
, check
);
162 test_convert_neg_float
<From
, To
>(from
, boost::mpl::bool_
<std::numeric_limits
<From
>::is_signed
&& std::numeric_limits
<To
>::is_signed
>());
167 template <class From
, class To
>
170 test_convert_imp
<From
, To
>(typename number_category
<From
>::type(), typename number_category
<To
>::type());
176 test_convert
<cpp_int
, int128_t
>();
177 test_convert
<int128_t
, cpp_int
>();
179 test_convert
<cpp_int
, cpp_rational
>();
180 test_convert
<int128_t
, cpp_rational
>();
181 test_convert
<uint128_t
, cpp_rational
>();
183 test_convert
<cpp_int
, cpp_bin_float_50
>();
184 test_convert
<int128_t
, cpp_bin_float_50
>();
185 test_convert
<uint128_t
, cpp_bin_float_50
>();
187 test_convert
<cpp_int
, cpp_dec_float_50
>();
188 test_convert
<int128_t
, cpp_dec_float_50
>();
189 test_convert
<uint128_t
, cpp_dec_float_50
>();
192 test_convert
<cpp_int
, mpz_int
>();
193 test_convert
<int128_t
, mpz_int
>();
194 test_convert
<uint128_t
, mpz_int
>();
196 test_convert
<cpp_int
, mpq_rational
>();
197 test_convert
<int128_t
, mpq_rational
>();
198 test_convert
<uint128_t
, mpq_rational
>();
200 test_convert
<cpp_int
, mpf_float_50
>();
201 test_convert
<int128_t
, mpf_float_50
>();
202 test_convert
<uint128_t
, mpf_float_50
>();
204 #if defined(HAS_MPFR)
205 test_convert
<cpp_int
, mpfr_float_50
>();
206 test_convert
<int128_t
, mpfr_float_50
>();
207 test_convert
<uint128_t
, mpfr_float_50
>();
209 #if defined(HAS_MPFI)
210 test_convert
<cpp_int
, mpfi_float_50
>();
211 test_convert
<int128_t
, mpfi_float_50
>();
212 test_convert
<uint128_t
, mpfi_float_50
>();
215 test_convert
<cpp_int
, tom_int
>();
216 test_convert
<int128_t
, tom_int
>();
217 test_convert
<uint128_t
, tom_int
>();
219 test_convert
<cpp_int
, tom_rational
>();
220 test_convert
<int128_t
, tom_rational
>();
221 test_convert
<uint128_t
, tom_rational
>();
224 test_convert
<cpp_int
, float128
>();
225 test_convert
<int128_t
, float128
>();
226 test_convert
<uint128_t
, float128
>();
228 return boost::report_errors();