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 https://www.boost.org/LICENSE_1_0.txt
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>
32 using namespace boost::multiprecision
;
35 #pragma warning(disable : 4127)
39 T
generate_random(unsigned bits_wanted
)
41 static boost::random::mt19937 gen
;
42 typedef boost::random::mt19937::result_type random_type
;
46 if (std::numeric_limits
<T
>::is_bounded
&& (bits_wanted
== (unsigned)std::numeric_limits
<T
>::digits
))
48 max_val
= (std::numeric_limits
<T
>::max
)();
49 digits
= std::numeric_limits
<T
>::digits
;
53 max_val
= T(1) << bits_wanted
;
57 unsigned bits_per_r_val
= std::numeric_limits
<random_type
>::digits
- 1;
58 while ((random_type(1) << bits_per_r_val
) > (gen
.max
)())
61 unsigned terms_needed
= digits
/ bits_per_r_val
+ 1;
64 for (unsigned i
= 0; i
< terms_needed
; ++i
)
73 template <class From
, class To
>
74 void test_convert_neg_int(From from
, const std::integral_constant
<bool, true>&)
78 To t4
= from
.template convert_to
<To
>();
79 BOOST_CHECK_EQUAL(from
.str(), t3
.str());
80 BOOST_CHECK_EQUAL(from
.str(), t4
.str());
82 template <class From
, class To
>
83 void test_convert_neg_int(From
const&, const std::integral_constant
<bool, false>&)
87 template <class From
, class To
>
88 void test_convert_imp(std::integral_constant
<int, number_kind_integer
> const&, std::integral_constant
<int, number_kind_integer
> const&)
90 int bits_wanted
= (std::min
)((std::min
)(std::numeric_limits
<From
>::digits
, std::numeric_limits
<To
>::digits
), 2000);
92 for (unsigned i
= 0; i
< 100; ++i
)
94 From from
= generate_random
<From
>(bits_wanted
);
96 To t2
= from
.template convert_to
<To
>();
97 BOOST_CHECK_EQUAL(from
.str(), t1
.str());
98 BOOST_CHECK_EQUAL(from
.str(), t2
.str());
99 test_convert_neg_int
<From
, To
>(from
, std::integral_constant
<bool, std::numeric_limits
<From
>::is_signed
&& std::numeric_limits
<To
>::is_signed
> ());
103 template <class From
, class To
>
104 void test_convert_neg_rat(From from
, const std::integral_constant
<bool, true>&)
108 To t4
= from
.template convert_to
<To
>();
109 BOOST_CHECK_EQUAL(from
.str(), numerator(t3
).str());
110 BOOST_CHECK_EQUAL(from
.str(), numerator(t4
).str());
112 template <class From
, class To
>
113 void test_convert_neg_rat(From
const&, const std::integral_constant
<bool, false>&)
117 template <class From
, class To
>
118 void test_convert_imp(std::integral_constant
<int, number_kind_integer
> const&, std::integral_constant
<int, number_kind_rational
> const&)
120 int bits_wanted
= (std::min
)((std::min
)(std::numeric_limits
<From
>::digits
, std::numeric_limits
<To
>::digits
), 2000);
122 for (unsigned i
= 0; i
< 100; ++i
)
124 From from
= generate_random
<From
>(bits_wanted
);
126 To t2
= from
.template convert_to
<To
>();
127 BOOST_CHECK_EQUAL(from
.str(), numerator(t1
).str());
128 BOOST_CHECK_EQUAL(from
.str(), numerator(t2
).str());
129 test_convert_neg_rat
<From
, To
>(from
, std::integral_constant
<bool, std::numeric_limits
<From
>::is_signed
&& std::numeric_limits
<To
>::is_signed
> ());
133 template <class From
, class To
>
134 void test_convert_neg_float(From from
, const std::integral_constant
<bool, true>&)
138 To t4
= from
.template convert_to
<To
>();
139 To
check(from
.str() + ".0");
140 BOOST_CHECK_EQUAL(t3
, check
);
141 BOOST_CHECK_EQUAL(t4
, check
);
143 template <class From
, class To
>
144 void test_convert_neg_float(From
const&, const std::integral_constant
<bool, false>&)
148 template <class From
, class To
>
149 void test_convert_imp(std::integral_constant
<int, number_kind_integer
> const&, std::integral_constant
<int, number_kind_floating_point
> const&)
151 int bits_wanted
= (std::min
)((std::min
)(std::numeric_limits
<From
>::digits
, std::numeric_limits
<To
>::digits
), 2000);
153 for (unsigned i
= 0; i
< 100; ++i
)
155 From from
= generate_random
<From
>(bits_wanted
);
157 To t2
= from
.template convert_to
<To
>();
158 To
check(from
.str() + ".0");
159 BOOST_CHECK_EQUAL(t1
, check
);
160 BOOST_CHECK_EQUAL(t2
, check
);
161 test_convert_neg_float
<From
, To
>(from
, std::integral_constant
<bool, std::numeric_limits
<From
>::is_signed
&& std::numeric_limits
<To
>::is_signed
> ());
165 template <class From
, class To
>
168 test_convert_imp
<From
, To
>(typename number_category
<From
>::type(), typename number_category
<To
>::type());
173 test_convert
<cpp_int
, int128_t
>();
174 test_convert
<int128_t
, cpp_int
>();
176 test_convert
<cpp_int
, cpp_rational
>();
177 test_convert
<int128_t
, cpp_rational
>();
178 test_convert
<uint128_t
, cpp_rational
>();
180 test_convert
<cpp_int
, cpp_bin_float_50
>();
181 test_convert
<int128_t
, cpp_bin_float_50
>();
182 test_convert
<uint128_t
, cpp_bin_float_50
>();
184 test_convert
<cpp_int
, cpp_dec_float_50
>();
185 test_convert
<int128_t
, cpp_dec_float_50
>();
186 test_convert
<uint128_t
, cpp_dec_float_50
>();
189 test_convert
<cpp_int
, mpz_int
>();
190 test_convert
<int128_t
, mpz_int
>();
191 test_convert
<uint128_t
, mpz_int
>();
193 test_convert
<cpp_int
, mpq_rational
>();
194 test_convert
<int128_t
, mpq_rational
>();
195 test_convert
<uint128_t
, mpq_rational
>();
197 test_convert
<cpp_int
, mpf_float_50
>();
198 test_convert
<int128_t
, mpf_float_50
>();
199 test_convert
<uint128_t
, mpf_float_50
>();
201 #if defined(HAS_MPFR)
202 test_convert
<cpp_int
, mpfr_float_50
>();
203 test_convert
<int128_t
, mpfr_float_50
>();
204 test_convert
<uint128_t
, mpfr_float_50
>();
206 #if defined(HAS_MPFI)
207 test_convert
<cpp_int
, mpfi_float_50
>();
208 test_convert
<int128_t
, mpfi_float_50
>();
209 test_convert
<uint128_t
, mpfi_float_50
>();
212 test_convert
<cpp_int
, tom_int
>();
213 test_convert
<int128_t
, tom_int
>();
214 test_convert
<uint128_t
, tom_int
>();
216 test_convert
<cpp_int
, tom_rational
>();
217 test_convert
<int128_t
, tom_rational
>();
218 test_convert
<uint128_t
, tom_rational
>();
221 test_convert
<cpp_int
, float128
>();
222 test_convert
<int128_t
, float128
>();
223 test_convert
<uint128_t
, float128
>();
225 return boost::report_errors();