]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/multiprecision/test/test_preserve_target_precision.cpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / libs / multiprecision / test / test_preserve_target_precision.cpp
CommitLineData
1e59de90
TL
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
5//
6
7#ifdef _MSC_VER
8#define _SCL_SECURE_NO_WARNINGS
9#endif
10
11#include <thread>
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>
17#include "test.hpp"
18
19#if !defined(TEST_MPF) && !defined(TEST_MPFR) && !defined(TEST_MPFI) && !defined(TEST_MPC)
20#define TEST_MPF
21#define TEST_MPFR
22#define TEST_MPFI
23#define TEST_MPC
24
25#ifdef _MSC_VER
26#pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!")
27#endif
28#ifdef __GNUC__
29#pragma warning "CAUTION!!: No backend type specified so testing everything.... this will take some time!!"
30#endif
31
32#endif
33
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>
38
39#if defined(TEST_MPFR)
40#include <boost/multiprecision/mpfr.hpp>
41#endif
42#if defined(TEST_MPFI)
43#include <boost/multiprecision/mpfi.hpp>
44#endif
45#if defined(TEST_MPC)
46#include <boost/multiprecision/mpc.hpp>
47#endif
48
49template <class T>
50T new_value()
51{
52 return T("0.1");
53}
54
55template <class Other>
56Other make_other_big_value()
57{
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))
61 {
62 using value_type = typename Other::value_type;
63 return Other(1) / ((value_type(1) << 1000) + 1);
64 }
65 else
66 return (std::numeric_limits<Other>::max)();
67}
68
69template <class T, class Other>
70void test_mixed()
71{
72 T::thread_default_precision(10);
73 T::thread_default_variable_precision_options(boost::multiprecision::variable_precision_options::preserve_target_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>());
75
76 T a(big_a);
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>)
81 {
82 a = big_b;
83 BOOST_CHECK_EQUAL(a.precision(), 10);
84 b = std::move(big_c);
85 BOOST_CHECK_EQUAL(a.precision(), 10);
86
87 if constexpr (!std::is_assignable_v<Other, T>)
88 {
89 a = b + big_a;
90 BOOST_CHECK_EQUAL(a.precision(), 10);
91 a = b * big_a;
92 BOOST_CHECK_EQUAL(a.precision(), 10);
93 a = b - big_a;
94 BOOST_CHECK_EQUAL(a.precision(), 10);
95 a = b / big_a;
96 BOOST_CHECK_EQUAL(a.precision(), 10);
97 a += big_a;
98 BOOST_CHECK_EQUAL(a.precision(), 10);
99 a -= big_a;
100 BOOST_CHECK_EQUAL(a.precision(), 10);
101 a *= big_a;
102 BOOST_CHECK_EQUAL(a.precision(), 10);
103 a /= big_a;
104 BOOST_CHECK_EQUAL(a.precision(), 10);
105 }
106 }
107 if constexpr (!std::is_same_v<T, typename T::value_type>)
108 {
109 T cc(big_a, big_b);
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);
115 aa.assign(big_a);
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>)
120 {
121 aa.assign(big_a, big_b, 55);
122 BOOST_CHECK_EQUAL(aa.precision(), 55);
123 }
124 }
125 else
126 {
127 if constexpr (std::is_constructible_v<T, Other, int>)
128 {
129 T aa(big_a, 55);
130 BOOST_CHECK_EQUAL(aa.precision(), 55);
131 aa.precision(10);
132 BOOST_CHECK_EQUAL(aa.precision(), 10);
133 aa.assign(big_a);
134 BOOST_CHECK_EQUAL(aa.precision(), 10);
135 aa.assign(big_a, 55);
136 BOOST_CHECK_EQUAL(aa.precision(), 55);
137 }
138 else
139 {
140 T aa;
141 BOOST_CHECK_EQUAL(aa.precision(), 10);
142 aa.assign(big_a);
143 BOOST_CHECK_EQUAL(aa.precision(), 10);
144 }
145 }
146}
147
148template <class T>
149void test()
150{
151 T::thread_default_precision(100);
152 T::thread_default_variable_precision_options(boost::multiprecision::variable_precision_options::preserve_target_precision);
153
154 T hp1("0.1"), hp2("0.3"), hp3("0.11"), hp4("0.1231");
155
156 BOOST_CHECK_EQUAL(hp1.precision(), 100);
157 BOOST_CHECK_EQUAL(hp2.precision(), 100);
158
159 T::thread_default_precision(35);
160
161 T a(hp1);
162 BOOST_CHECK_EQUAL(a.precision(), 35);
163 a = hp1;
164 BOOST_CHECK_EQUAL(a.precision(), 35);
165 a = std::move(hp1);
166 BOOST_CHECK_EQUAL(a.precision(), 35);
167 T b(std::move(hp2));
168 BOOST_CHECK_EQUAL(b.precision(), 35);
169
170 a = b + hp3;
171 BOOST_CHECK_EQUAL(a.precision(), 35);
172 a = hp3 * b;
173 BOOST_CHECK_EQUAL(a.precision(), 35);
174 a += hp3;
175 BOOST_CHECK_EQUAL(a.precision(), 35);
176 a *= hp4;
177 BOOST_CHECK_EQUAL(a.precision(), 35);
178 a -= b * hp3;
179 BOOST_CHECK_EQUAL(a.precision(), 35);
180
181 if constexpr (!std::is_same_v<T, typename T::value_type>)
182 {
183 //
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:
186 //
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);
190
191 component_t cp1("0.1"), cp2("0.3"), cp3("0.11"), cp4("0.1231");
192
193 BOOST_CHECK_EQUAL(cp1.precision(), 100);
194 BOOST_CHECK_EQUAL(cp2.precision(), 100);
195
196 T::thread_default_precision(35);
197
198 T aa(cp1);
199 BOOST_CHECK_EQUAL(aa.precision(), 35);
200 T cc(cp1, cp2);
201 BOOST_CHECK_EQUAL(cc.precision(), 35);
202 T dd(cp1, cp2, 20);
203 BOOST_CHECK_EQUAL(dd.precision(), 20);
204 aa = cp1;
205 BOOST_CHECK_EQUAL(aa.precision(), 35);
206 aa = std::move(cp1);
207 BOOST_CHECK_EQUAL(aa.precision(), 35);
208 T bb(std::move(cp2));
209 BOOST_CHECK_EQUAL(bb.precision(), 35);
210
211 aa = bb + cp3;
212 BOOST_CHECK_EQUAL(aa.precision(), 35);
213 aa = cp3 * bb;
214 BOOST_CHECK_EQUAL(aa.precision(), 35);
215 aa += cp3;
216 BOOST_CHECK_EQUAL(aa.precision(), 35);
217 aa -= cp3;
218 BOOST_CHECK_EQUAL(aa.precision(), 35);
219 aa *= cp4;
220 BOOST_CHECK_EQUAL(aa.precision(), 35);
221 aa /= cp4;
222 BOOST_CHECK_EQUAL(aa.precision(), 35);
223 aa -= bb * cp3;
224 BOOST_CHECK_EQUAL(aa.precision(), 35);
225
226 aa.assign(cp1);
227 BOOST_CHECK_EQUAL(aa.precision(), 35);
228 aa.assign(cp1, cp2);
229 BOOST_CHECK_EQUAL(aa.precision(), 35);
230 aa.assign(cp1, cp2, 20);
231 BOOST_CHECK_EQUAL(aa.precision(), 20);
232 }
233 else
234 {
235 T aa(hp4, 20);
236 BOOST_CHECK_EQUAL(aa.precision(), 20);
237 aa.precision(35);
238 aa.assign(hp4);
239 BOOST_CHECK_EQUAL(aa.precision(), 35);
240 aa.assign(hp4, 20);
241 BOOST_CHECK_EQUAL(aa.precision(), 20);
242 }
243
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>();
258 //
259 // Test with other compatible multiprecision types:
260 //
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>();
270#endif
271}
272
273int main()
274{
275#ifdef TEST_MPF
276 test<boost::multiprecision::mpf_float>();
277 test<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, boost::multiprecision::et_off>>();
278#endif
279#ifdef TEST_MPFR
280 test<boost::multiprecision::mpfr_float>();
281 test<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> >();
282#endif
283#ifdef TEST_MPFI
284 test<boost::multiprecision::mpfi_float>();
285 test<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, boost::multiprecision::et_off> >();
286#endif
287#ifdef TEST_MPC
288 test<boost::multiprecision::mpc_complex>();
289 test<boost::multiprecision::number<boost::multiprecision::mpc_complex_backend<0>, boost::multiprecision::et_off> >();
290#endif
291 return boost::report_errors();
292}