1 ///////////////////////////////////////////////////////////////
2 // Copyright 2021 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
8 #define _SCL_SECURE_NO_WARNINGS
12 #include <boost/detail/lightweight_test.hpp>
13 #include <boost/array.hpp>
14 #include <boost/math/special_functions/relative_difference.hpp>
15 #include <boost/math/special_functions/gamma.hpp>
16 #include <boost/math/quadrature/tanh_sinh.hpp>
19 #if !defined(TEST_MPF) && !defined(TEST_MPFR) && !defined(TEST_MPFI) && !defined(TEST_MPC)
26 #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!")
29 #pragma warning "CAUTION!!: No backend type specified so testing everything.... this will take some time!!"
34 #include <boost/multiprecision/gmp.hpp>
35 #include <boost/multiprecision/cpp_int.hpp>
36 #include <boost/multiprecision/cpp_bin_float.hpp>
37 #include <boost/multiprecision/cpp_dec_float.hpp>
39 #if defined(TEST_MPFR)
40 #include <boost/multiprecision/mpfr.hpp>
42 #if defined(TEST_MPFI)
43 #include <boost/multiprecision/mpfi.hpp>
46 #include <boost/multiprecision/mpc.hpp>
55 template <class Other
>
56 Other
make_other_big_value()
58 if constexpr (std::numeric_limits
<Other
>::is_integer
&& !std::numeric_limits
<Other
>::is_bounded
)
59 return (Other(1) << 1000) + 1;
60 else if constexpr (!std::numeric_limits
<Other
>::is_integer
&& std::numeric_limits
<Other
>::is_exact
&& (std::numeric_limits
<Other
>::max_exponent
== std::numeric_limits
<Other
>::min_exponent
))
62 using value_type
= typename
Other::value_type
;
63 return Other(1) / ((value_type(1) << 1000) + 1);
66 return (std::numeric_limits
<Other
>::max
)();
69 template <class T
, class Other
>
72 T::thread_default_precision(10);
73 T::thread_default_variable_precision_options(boost::multiprecision::variable_precision_options::assume_uniform_precision
);
74 Other
big_a(make_other_big_value
<Other
>()), big_b(make_other_big_value
<Other
>()), big_c(make_other_big_value
<Other
>()), big_d(make_other_big_value
<Other
>());
77 BOOST_CHECK_EQUAL(a
.precision(), 10);
78 T
b(std::move(big_d
));
79 BOOST_CHECK_EQUAL(a
.precision(), 10);
80 if constexpr (std::is_assignable_v
<T
, Other
>)
83 BOOST_CHECK_EQUAL(a
.precision(), 10);
85 BOOST_CHECK_EQUAL(a
.precision(), 10);
87 if constexpr (!std::is_assignable_v
<Other
, T
>)
90 BOOST_CHECK_EQUAL(a
.precision(), 10);
92 BOOST_CHECK_EQUAL(a
.precision(), 10);
94 BOOST_CHECK_EQUAL(a
.precision(), 10);
96 BOOST_CHECK_EQUAL(a
.precision(), 10);
98 BOOST_CHECK_EQUAL(a
.precision(), 10);
100 BOOST_CHECK_EQUAL(a
.precision(), 10);
102 BOOST_CHECK_EQUAL(a
.precision(), 10);
104 BOOST_CHECK_EQUAL(a
.precision(), 10);
107 if constexpr (!std::is_same_v
<T
, typename
T::value_type
>)
110 BOOST_CHECK_EQUAL(cc
.precision(), 10);
111 T
dd(big_a
, big_b
, 55);
112 BOOST_CHECK_EQUAL(dd
.precision(), 55);
113 T aa
= new_value
<T
>();
114 BOOST_CHECK_EQUAL(aa
.precision(), 10);
116 BOOST_CHECK_EQUAL(aa
.precision(), 10);
117 aa
.assign(big_a
, big_b
);
118 BOOST_CHECK_EQUAL(aa
.precision(), 10);
119 if constexpr (0 && std::is_constructible_v
<T
, Other
, Other
, int>)
121 aa
.assign(big_a
, big_b
, 55);
122 BOOST_CHECK_EQUAL(aa
.precision(), 55);
127 if constexpr (std::is_constructible_v
<T
, Other
, int>)
130 BOOST_CHECK_EQUAL(aa
.precision(), 55);
132 BOOST_CHECK_EQUAL(aa
.precision(), 10);
134 BOOST_CHECK_EQUAL(aa
.precision(), 10);
135 aa
.assign(big_a
, 55);
136 BOOST_CHECK_EQUAL(aa
.precision(), 55);
141 BOOST_CHECK_EQUAL(aa
.precision(), 10);
143 BOOST_CHECK_EQUAL(aa
.precision(), 10);
151 T::thread_default_precision(100);
152 T::thread_default_variable_precision_options(boost::multiprecision::variable_precision_options::assume_uniform_precision
);
154 T
hp1("0.1"), hp2("0.3"), hp3("0.11"), hp4("0.1231");
156 BOOST_CHECK_EQUAL(hp1
.precision(), 100);
157 BOOST_CHECK_EQUAL(hp2
.precision(), 100);
159 T::thread_default_precision(35);
162 BOOST_CHECK_EQUAL(a
.precision(), 35);
164 BOOST_CHECK_EQUAL(a
.precision(), 35);
166 BOOST_CHECK_EQUAL(a
.precision(), 100);
168 BOOST_CHECK_EQUAL(b
.precision(), 100);
171 BOOST_CHECK_EQUAL(a
.precision(), 35);
173 BOOST_CHECK_EQUAL(a
.precision(), 35);
175 BOOST_CHECK_EQUAL(a
.precision(), 35);
177 BOOST_CHECK_EQUAL(a
.precision(), 35);
179 BOOST_CHECK_EQUAL(a
.precision(), 35);
181 if constexpr (!std::is_same_v
<T
, typename
T::value_type
>)
184 // If we have a component type: ie we are an interval or a complex number, then
185 // operations involving the component type should match those of T:
187 using component_t
= typename
T::value_type
;
188 component_t::thread_default_precision(100);
189 component_t::thread_default_variable_precision_options(boost::multiprecision::variable_precision_options::preserve_source_precision
);
191 component_t
cp1("0.1"), cp2("0.3"), cp3("0.11"), cp4("0.1231");
193 BOOST_CHECK_EQUAL(cp1
.precision(), 100);
194 BOOST_CHECK_EQUAL(cp2
.precision(), 100);
196 T::thread_default_precision(35);
199 BOOST_CHECK_EQUAL(aa
.precision(), 35);
201 BOOST_CHECK_EQUAL(cc
.precision(), 35);
203 BOOST_CHECK_EQUAL(dd
.precision(), 20);
205 BOOST_CHECK_EQUAL(aa
.precision(), 35);
207 BOOST_CHECK_EQUAL(aa
.precision(), 35);
208 T
bb(std::move(cp2
));
209 BOOST_CHECK_EQUAL(bb
.precision(), 35);
212 BOOST_CHECK_EQUAL(aa
.precision(), 35);
214 BOOST_CHECK_EQUAL(aa
.precision(), 35);
216 BOOST_CHECK_EQUAL(aa
.precision(), 35);
218 BOOST_CHECK_EQUAL(aa
.precision(), 35);
220 BOOST_CHECK_EQUAL(aa
.precision(), 35);
222 BOOST_CHECK_EQUAL(aa
.precision(), 35);
224 BOOST_CHECK_EQUAL(aa
.precision(), 35);
227 BOOST_CHECK_EQUAL(aa
.precision(), 35);
229 BOOST_CHECK_EQUAL(aa
.precision(), 35);
230 aa
.assign(cp1
, cp2
, 20);
231 BOOST_CHECK_EQUAL(aa
.precision(), 20);
236 BOOST_CHECK_EQUAL(aa
.precision(), 20);
239 BOOST_CHECK_EQUAL(aa
.precision(), 35);
241 BOOST_CHECK_EQUAL(aa
.precision(), 20);
244 test_mixed
<T
, char>();
245 test_mixed
<T
, unsigned char>();
246 test_mixed
<T
, signed char>();
247 test_mixed
<T
, short>();
248 test_mixed
<T
, unsigned short>();
249 test_mixed
<T
, int>();
250 test_mixed
<T
, unsigned int>();
251 test_mixed
<T
, long>();
252 test_mixed
<T
, unsigned long>();
253 test_mixed
<T
, long long>();
254 test_mixed
<T
, unsigned long long>();
255 test_mixed
<T
, float>();
256 test_mixed
<T
, double>();
257 test_mixed
<T
, long double>();
259 // Test with other compatible multiprecision types:
261 test_mixed
<T
, boost::multiprecision::mpz_int
>();
262 test_mixed
<T
, boost::multiprecision::cpp_int
>();
263 test_mixed
<T
, boost::multiprecision::mpq_rational
>();
264 test_mixed
<T
, boost::multiprecision::cpp_rational
>();
265 test_mixed
<T
, boost::multiprecision::cpp_bin_float_100
>();
266 test_mixed
<T
, boost::multiprecision::cpp_dec_float_100
>();
267 test_mixed
<T
, boost::multiprecision::mpf_float_100
>();
268 #if defined(TEST_MPFR) || defined(TEST_MPC) || defined(TEST_MPFI)
269 test_mixed
<T
, boost::multiprecision::mpfr_float_100
>();
276 test
<boost::multiprecision::mpf_float
>();
277 test
<boost::multiprecision::number
<boost::multiprecision::gmp_float
<0>, boost::multiprecision::et_off
>>();
280 test
<boost::multiprecision::mpfr_float
>();
281 test
<boost::multiprecision::number
<boost::multiprecision::mpfr_float_backend
<0>, boost::multiprecision::et_off
> >();
284 test
<boost::multiprecision::mpfi_float
>();
285 test
<boost::multiprecision::number
<boost::multiprecision::mpfi_float_backend
<0>, boost::multiprecision::et_off
> >();
288 test
<boost::multiprecision::mpc_complex
>();
289 test
<boost::multiprecision::number
<boost::multiprecision::mpc_complex_backend
<0>, boost::multiprecision::et_off
> >();
291 return boost::report_errors();