Imported Upstream version 1.72.0
[platform/upstream/boost.git] / libs / multiprecision / test / test_round.cpp
1 //  (C) Copyright John Maddock 2007.
2 //  Use, modification and distribution are subject to the
3 //  Boost Software License, Version 1.0. (See accompanying file
4 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6 #ifdef _MSC_VER
7 #define _SCL_SECURE_NO_WARNINGS
8 #endif
9
10 #include <boost/detail/lightweight_test.hpp>
11 #include <boost/math/special_functions/round.hpp>
12 #include <boost/math/special_functions/trunc.hpp>
13 #include <boost/math/special_functions/modf.hpp>
14 #include <boost/math/special_functions/sign.hpp>
15 #include <boost/random/mersenne_twister.hpp>
16 #include "test.hpp"
17
18 #if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50) && !defined(TEST_FLOAT128) && !defined(TEST_CPP_BIN_FLOAT)
19 #define TEST_MPF_50
20 #define TEST_MPFR_50
21 #define TEST_MPFI_50
22 #define TEST_BACKEND
23 #define TEST_CPP_DEC_FLOAT
24 #define TEST_FLOAT128
25 #define TEST_CPP_BIN_FLOAT
26
27 #ifdef _MSC_VER
28 #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!")
29 #endif
30 #ifdef __GNUC__
31 #pragma warning "CAUTION!!: No backend type specified so testing everything.... this will take some time!!"
32 #endif
33
34 #endif
35
36 #if defined(TEST_MPF_50)
37 #include <boost/multiprecision/gmp.hpp>
38 #endif
39 #ifdef TEST_MPFR_50
40 #include <boost/multiprecision/mpfr.hpp>
41 #endif
42 #ifdef TEST_MPFI_50
43 #include <boost/multiprecision/mpfi.hpp>
44 #endif
45 #ifdef TEST_BACKEND
46 #include <boost/multiprecision/concepts/mp_number_archetypes.hpp>
47 #endif
48 #ifdef TEST_CPP_DEC_FLOAT
49 #include <boost/multiprecision/cpp_dec_float.hpp>
50 #endif
51 #ifdef TEST_CPP_BIN_FLOAT
52 #include <boost/multiprecision/cpp_bin_float.hpp>
53 #endif
54 #ifdef TEST_FLOAT128
55 #include <boost/multiprecision/float128.hpp>
56 #endif
57
58 #ifdef BOOST_MSVC
59 #pragma warning(disable : 4127)
60 #endif
61
62 boost::mt19937 rng;
63
64 template <class T>
65 T get_random()
66 {
67    //
68    // Fill all the bits in T with random values,
69    // likewise set the exponent to a random value
70    // that will still fit inside a T, and always
71    // have a remainder as well as an integer part.
72    //
73    int bits     = boost::math::tools::digits<T>();
74    int shift    = 0;
75    int exponent = rng() % (bits - 4);
76    T   result   = 0;
77    while (bits > 0)
78    {
79       result += ldexp(static_cast<T>(rng()), shift);
80       shift += std::numeric_limits<int>::digits;
81       bits -= std::numeric_limits<int>::digits;
82    }
83    return rng() & 1u ? T(-ldexp(frexp(result, &bits), exponent)) : T(ldexp(frexp(result, &bits), exponent));
84 }
85
86 template <class T, class U>
87 typename boost::disable_if_c<boost::multiprecision::is_interval_number<T>::value>::type check_within_half(T a, U u)
88 {
89    BOOST_MATH_STD_USING
90    if (fabs(a - u) > 0.5f)
91    {
92       BOOST_ERROR("Rounded result differed by more than 0.5 from the original");
93       std::cerr << "Values were: " << std::setprecision(35) << std::setw(40)
94                 << std::left << a << u << std::endl;
95    }
96    if ((fabs(a - u) == 0.5f) && (fabs(static_cast<T>(u)) < fabs(a)))
97    {
98       BOOST_ERROR("Rounded result was towards zero with boost::round");
99       std::cerr << "Values were: " << std::setprecision(35) << std::setw(40)
100                 << std::left << a << u << std::endl;
101    }
102 }
103 template <class T, class U>
104 typename boost::enable_if_c<boost::multiprecision::is_interval_number<T>::value>::type check_within_half(T a, U u)
105 {
106    BOOST_MATH_STD_USING
107    if (upper(T(fabs(a - u))) > 0.5f)
108    {
109       BOOST_ERROR("Rounded result differed by more than 0.5 from the original");
110       std::cerr << "Values were: " << std::setprecision(35) << std::setw(40)
111                 << std::left << a << u << std::endl;
112    }
113    if ((upper(T(fabs(a - u))) == 0.5f) && (fabs(static_cast<T>(u)) < fabs(a)))
114    {
115       BOOST_ERROR("Rounded result was towards zero with boost::round");
116       std::cerr << "Values were: " << std::setprecision(35) << std::setw(40)
117                 << std::left << a << u << std::endl;
118    }
119 }
120
121 //
122 // We may not have an abs overload for long long so provide a fall back:
123 //
124 inline unsigned safe_abs(int const& v)
125 {
126    return v < 0 ? static_cast<unsigned>(1u) + static_cast<unsigned>(-(v + 1)) : v;
127 }
128 inline unsigned long safe_abs(long const& v)
129 {
130    return v < 0 ? static_cast<unsigned long>(1u) + static_cast<unsigned long>(-(v + 1)) : v;
131 }
132 inline unsigned long long safe_abs(long long const& v)
133 {
134    return v < 0 ? static_cast<unsigned long long>(1u) + static_cast<unsigned long long>(-(v + 1)) : v;
135 }
136 template <class T>
137 inline typename boost::disable_if_c<boost::is_integral<T>::value, T>::type safe_abs(T const& v)
138 {
139    return v < 0 ? -v : v;
140 }
141
142 template <class T, class U>
143 void check_trunc_result(T a, U u)
144 {
145    BOOST_MATH_STD_USING
146    if (fabs(a - u) >= 1)
147    {
148       BOOST_ERROR("Rounded result differed by more than 1 from the original");
149       std::cerr << "Values were: " << std::setprecision(35) << std::setw(40)
150                 << std::left << a << u << std::endl;
151    }
152    if (abs(a) < safe_abs(u))
153    {
154       BOOST_ERROR("Truncated result had larger absolute value than the original");
155       std::cerr << "Values were: " << std::setprecision(35) << std::setw(40)
156                 << std::left << a << u << std::endl;
157    }
158    if (fabs(static_cast<T>(u)) > fabs(a))
159    {
160       BOOST_ERROR("Rounded result was away from zero with boost::trunc");
161       std::cerr << "Values were: " << std::setprecision(35) << std::setw(40)
162                 << std::left << a << u << std::endl;
163    }
164 }
165
166 template <class T, class U>
167 void check_modf_result(T a, T fract, U ipart)
168 {
169    BOOST_MATH_STD_USING
170    if (fract + ipart != a)
171    {
172       BOOST_ERROR("Fractional and integer results do not add up to the original value");
173       std::cerr << "Values were: " << std::setprecision(35) << " "
174                 << std::left << a << ipart << " " << fract << std::endl;
175    }
176    if ((boost::math::sign(a) != boost::math::sign(fract)) && boost::math::sign(fract))
177    {
178       BOOST_ERROR("Original and fractional parts have differing signs");
179       std::cerr << "Values were: " << std::setprecision(35) << " "
180                 << std::left << a << ipart << " " << fract << std::endl;
181    }
182    if ((boost::math::sign(a) != boost::math::sign(ipart)) && boost::math::sign(ipart))
183    {
184       BOOST_ERROR("Original and integer parts have differing signs");
185       std::cerr << "Values were: " << std::setprecision(35) << " "
186                 << std::left << a << ipart << " " << ipart << std::endl;
187    }
188    if (fabs(a - ipart) >= 1)
189    {
190       BOOST_ERROR("Rounded result differed by more than 1 from the original");
191       std::cerr << "Values were: " << std::setprecision(35) << std::setw(40)
192                 << std::left << a << ipart << std::endl;
193    }
194 }
195
196 template <class T>
197 void test()
198 {
199    BOOST_MATH_STD_USING
200
201    for (int i = 0; i < 1000; ++i)
202    {
203       T arg = get_random<T>();
204       T r   = round(arg);
205       check_within_half(arg, r);
206       BOOST_TEST(r == round(arg + 0));
207       r = trunc(arg);
208       check_trunc_result(arg, r);
209       BOOST_TEST(r == trunc(arg + 0));
210       T frac = modf(arg, &r);
211       check_modf_result(arg, frac, r);
212
213       if (abs(r) < (std::numeric_limits<int>::max)())
214       {
215          int i = iround(arg);
216          check_within_half(arg, i);
217          BOOST_TEST(i == iround(arg + 0));
218          i = itrunc(arg);
219          check_trunc_result(arg, i);
220          BOOST_TEST(i == itrunc(arg + 0));
221          r = modf(arg, &i);
222          check_modf_result(arg, r, i);
223       }
224       if (abs(r) < (std::numeric_limits<long>::max)())
225       {
226          long l = lround(arg);
227          check_within_half(arg, l);
228          BOOST_TEST(l == lround(arg + 0));
229          l = ltrunc(arg);
230          check_trunc_result(arg, l);
231          BOOST_TEST(l == ltrunc(arg + 0));
232          r = modf(arg, &l);
233          check_modf_result(arg, r, l);
234       }
235
236 #ifdef BOOST_HAS_LONG_LONG
237       if (abs(r) < (std::numeric_limits<boost::long_long_type>::max)())
238       {
239          boost::long_long_type ll = llround(arg);
240          check_within_half(arg, ll);
241          BOOST_TEST(ll == llround(arg + 0));
242          ll = lltrunc(arg);
243          check_trunc_result(arg, ll);
244          BOOST_TEST(ll == lltrunc(arg + 0));
245          r = modf(arg, &ll);
246          check_modf_result(arg, r, ll);
247       }
248 #endif
249    }
250    //
251    // Test boundary cases:
252    //
253    if (std::numeric_limits<T>::digits >= std::numeric_limits<int>::digits)
254    {
255       int si = iround(static_cast<T>((std::numeric_limits<int>::max)()));
256       check_within_half(static_cast<T>((std::numeric_limits<int>::max)()), si);
257       BOOST_TEST(si == iround(static_cast<T>((std::numeric_limits<int>::max)()) + 0));
258       si = iround(static_cast<T>((std::numeric_limits<int>::min)()));
259       check_within_half(static_cast<T>((std::numeric_limits<int>::min)()), si);
260       BOOST_TEST(si == iround(static_cast<T>((std::numeric_limits<int>::min)()) + 0));
261       si = itrunc(static_cast<T>((std::numeric_limits<int>::max)()));
262       check_trunc_result(static_cast<T>((std::numeric_limits<int>::max)()), si);
263       BOOST_TEST(si == itrunc(static_cast<T>((std::numeric_limits<int>::max)()) + 0));
264       si = itrunc(static_cast<T>((std::numeric_limits<int>::min)()));
265       check_trunc_result(static_cast<T>((std::numeric_limits<int>::min)()), si);
266       BOOST_TEST(si == itrunc(static_cast<T>((std::numeric_limits<int>::min)()) + 0));
267
268       si = iround(static_cast<T>((std::numeric_limits<int>::max)() - 1));
269       check_within_half(static_cast<T>((std::numeric_limits<int>::max)() - 1), si);
270       si = iround(static_cast<T>((std::numeric_limits<int>::min)() + 1));
271       check_within_half(static_cast<T>((std::numeric_limits<int>::min)() + 1), si);
272       si = itrunc(static_cast<T>((std::numeric_limits<int>::max)() - 1));
273       check_trunc_result(static_cast<T>((std::numeric_limits<int>::max)() - 1), si);
274       si = itrunc(static_cast<T>((std::numeric_limits<int>::min)() + 1));
275       check_trunc_result(static_cast<T>((std::numeric_limits<int>::min)() + 1), si);
276    }
277    if (std::numeric_limits<T>::digits >= std::numeric_limits<long>::digits)
278    {
279       long k = lround(static_cast<T>((std::numeric_limits<long>::max)()));
280       check_within_half(static_cast<T>((std::numeric_limits<long>::max)()), k);
281       BOOST_TEST(k == lround(static_cast<T>((std::numeric_limits<long>::max)()) + 0));
282       k = lround(static_cast<T>((std::numeric_limits<long>::min)()));
283       check_within_half(static_cast<T>((std::numeric_limits<long>::min)()), k);
284       BOOST_TEST(k == lround(static_cast<T>((std::numeric_limits<long>::min)()) + 0));
285       k = ltrunc(static_cast<T>((std::numeric_limits<long>::max)()));
286       check_trunc_result(static_cast<T>((std::numeric_limits<long>::max)()), k);
287       BOOST_TEST(k == ltrunc(static_cast<T>((std::numeric_limits<long>::max)()) + 0));
288       k = ltrunc(static_cast<T>((std::numeric_limits<long>::min)()));
289       check_trunc_result(static_cast<T>((std::numeric_limits<long>::min)()), k);
290       BOOST_TEST(k == ltrunc(static_cast<T>((std::numeric_limits<long>::min)()) + 0));
291
292       k = lround(static_cast<T>((std::numeric_limits<long>::max)() - 1));
293       check_within_half(static_cast<T>((std::numeric_limits<long>::max)() - 1), k);
294       k = lround(static_cast<T>((std::numeric_limits<long>::min)() + 1));
295       check_within_half(static_cast<T>((std::numeric_limits<long>::min)() + 1), k);
296       k = ltrunc(static_cast<T>((std::numeric_limits<long>::max)() - 1));
297       check_trunc_result(static_cast<T>((std::numeric_limits<long>::max)() - 1), k);
298       k = ltrunc(static_cast<T>((std::numeric_limits<long>::min)() + 1));
299       check_trunc_result(static_cast<T>((std::numeric_limits<long>::min)() + 1), k);
300    }
301 #ifndef BOOST_NO_LONG_LONG
302    if (std::numeric_limits<T>::digits >= std::numeric_limits<boost::long_long_type>::digits)
303    {
304       boost::long_long_type j = llround(static_cast<T>((std::numeric_limits<boost::long_long_type>::max)()));
305       check_within_half(static_cast<T>((std::numeric_limits<boost::long_long_type>::max)()), j);
306       BOOST_TEST(j == llround(static_cast<T>((std::numeric_limits<long long>::max)()) + 0));
307       j = llround(static_cast<T>((std::numeric_limits<boost::long_long_type>::min)()));
308       check_within_half(static_cast<T>((std::numeric_limits<boost::long_long_type>::min)()), j);
309       BOOST_TEST(j == llround(static_cast<T>((std::numeric_limits<long long>::min)()) + 0));
310       j = lltrunc(static_cast<T>((std::numeric_limits<boost::long_long_type>::max)()));
311       check_trunc_result(static_cast<T>((std::numeric_limits<boost::long_long_type>::max)()), j);
312       BOOST_TEST(j == lltrunc(static_cast<T>((std::numeric_limits<long long>::max)()) + 0));
313       j = lltrunc(static_cast<T>((std::numeric_limits<boost::long_long_type>::min)()));
314       check_trunc_result(static_cast<T>((std::numeric_limits<boost::long_long_type>::min)()), j);
315       BOOST_TEST(j == lltrunc(static_cast<T>((std::numeric_limits<long long>::min)()) + 0));
316
317       j = llround(static_cast<T>((std::numeric_limits<boost::long_long_type>::max)() - 1));
318       check_within_half(static_cast<T>((std::numeric_limits<boost::long_long_type>::max)() - 1), j);
319       j = llround(static_cast<T>((std::numeric_limits<boost::long_long_type>::min)() + 1));
320       check_within_half(static_cast<T>((std::numeric_limits<boost::long_long_type>::min)() + 1), j);
321       j = lltrunc(static_cast<T>((std::numeric_limits<boost::long_long_type>::max)() - 1));
322       check_trunc_result(static_cast<T>((std::numeric_limits<boost::long_long_type>::max)() - 1), j);
323       j = lltrunc(static_cast<T>((std::numeric_limits<boost::long_long_type>::min)() + 1));
324       check_trunc_result(static_cast<T>((std::numeric_limits<boost::long_long_type>::min)() + 1), j);
325    }
326 #endif
327    //
328    // Finish off by testing the error handlers:
329    //
330    T result;
331 #ifndef BOOST_NO_EXCEPTIONS
332    BOOST_CHECK_THROW(result = static_cast<T>(iround(static_cast<T>(1e20))), boost::math::rounding_error);
333    BOOST_CHECK_THROW(result = static_cast<T>(iround(static_cast<T>(-1e20))), boost::math::rounding_error);
334    BOOST_CHECK_THROW(result = static_cast<T>(lround(static_cast<T>(1e20))), boost::math::rounding_error);
335    BOOST_CHECK_THROW(result = static_cast<T>(lround(static_cast<T>(-1e20))), boost::math::rounding_error);
336 #ifdef BOOST_HAS_LONG_LONG
337    BOOST_CHECK_THROW(result = static_cast<T>(llround(static_cast<T>(1e20))), boost::math::rounding_error);
338    BOOST_CHECK_THROW(result = static_cast<T>(llround(static_cast<T>(-1e20))), boost::math::rounding_error);
339 #endif
340    if (std::numeric_limits<T>::has_infinity)
341    {
342       BOOST_CHECK_EQUAL(static_cast<T>(round(std::numeric_limits<T>::infinity())), std::numeric_limits<T>::infinity()); // See C99 Annex F.
343       BOOST_CHECK_THROW(result = static_cast<T>(iround(std::numeric_limits<T>::infinity())), boost::math::rounding_error);
344       BOOST_CHECK_THROW(result = static_cast<T>(iround(-std::numeric_limits<T>::infinity())), boost::math::rounding_error);
345       BOOST_CHECK_THROW(result = static_cast<T>(lround(std::numeric_limits<T>::infinity())), boost::math::rounding_error);
346       BOOST_CHECK_THROW(result = static_cast<T>(lround(-std::numeric_limits<T>::infinity())), boost::math::rounding_error);
347 #ifdef BOOST_HAS_LONG_LONG
348       BOOST_CHECK_THROW(result = static_cast<T>(llround(std::numeric_limits<T>::infinity())), boost::math::rounding_error);
349       BOOST_CHECK_THROW(result = static_cast<T>(llround(-std::numeric_limits<T>::infinity())), boost::math::rounding_error);
350 #endif
351    }
352    if (std::numeric_limits<T>::has_quiet_NaN)
353    {
354       BOOST_CHECK((boost::multiprecision::isnan)(round(std::numeric_limits<T>::quiet_NaN())));
355       BOOST_CHECK_THROW(result = static_cast<T>(iround(std::numeric_limits<T>::quiet_NaN())), boost::math::rounding_error);
356       BOOST_CHECK_THROW(result = static_cast<T>(lround(std::numeric_limits<T>::quiet_NaN())), boost::math::rounding_error);
357 #ifdef BOOST_HAS_LONG_LONG
358       BOOST_CHECK_THROW(result = static_cast<T>(llround(std::numeric_limits<T>::quiet_NaN())), boost::math::rounding_error);
359 #endif
360    }
361    BOOST_CHECK_THROW(result = static_cast<T>(itrunc(static_cast<T>(1e20))), boost::math::rounding_error);
362    BOOST_CHECK_THROW(result = static_cast<T>(itrunc(static_cast<T>(-1e20))), boost::math::rounding_error);
363    BOOST_CHECK_THROW(result = static_cast<T>(ltrunc(static_cast<T>(1e20))), boost::math::rounding_error);
364    BOOST_CHECK_THROW(result = static_cast<T>(ltrunc(static_cast<T>(-1e20))), boost::math::rounding_error);
365 #ifdef BOOST_HAS_LONG_LONG
366    BOOST_CHECK_THROW(result = static_cast<T>(lltrunc(static_cast<T>(1e20))), boost::math::rounding_error);
367    BOOST_CHECK_THROW(result = static_cast<T>(lltrunc(static_cast<T>(-1e20))), boost::math::rounding_error);
368 #endif
369    if (std::numeric_limits<T>::has_infinity)
370    {
371       BOOST_CHECK_EQUAL(static_cast<T>(trunc(std::numeric_limits<T>::infinity())), std::numeric_limits<T>::infinity());
372       BOOST_CHECK_EQUAL(static_cast<T>(trunc(-std::numeric_limits<T>::infinity())), -std::numeric_limits<T>::infinity());
373       BOOST_CHECK_THROW(result = static_cast<T>(itrunc(std::numeric_limits<T>::infinity())), boost::math::rounding_error);
374       BOOST_CHECK_THROW(result = static_cast<T>(itrunc(-std::numeric_limits<T>::infinity())), boost::math::rounding_error);
375       BOOST_CHECK_THROW(result = static_cast<T>(ltrunc(std::numeric_limits<T>::infinity())), boost::math::rounding_error);
376       BOOST_CHECK_THROW(result = static_cast<T>(ltrunc(-std::numeric_limits<T>::infinity())), boost::math::rounding_error);
377 #ifdef BOOST_HAS_LONG_LONG
378       BOOST_CHECK_THROW(result = static_cast<T>(lltrunc(std::numeric_limits<T>::infinity())), boost::math::rounding_error);
379       BOOST_CHECK_THROW(result = static_cast<T>(lltrunc(-std::numeric_limits<T>::infinity())), boost::math::rounding_error);
380 #endif
381    }
382    if (std::numeric_limits<T>::has_quiet_NaN)
383    {
384       BOOST_CHECK((boost::multiprecision::isnan)(trunc(std::numeric_limits<T>::quiet_NaN())));
385       BOOST_CHECK_THROW(result = static_cast<T>(itrunc(std::numeric_limits<T>::quiet_NaN())), boost::math::rounding_error);
386       BOOST_CHECK_THROW(result = static_cast<T>(ltrunc(std::numeric_limits<T>::quiet_NaN())), boost::math::rounding_error);
387 #ifdef BOOST_HAS_LONG_LONG
388       BOOST_CHECK_THROW(result = static_cast<T>(lltrunc(std::numeric_limits<T>::quiet_NaN())), boost::math::rounding_error);
389 #endif
390    }
391    if (std::numeric_limits<T>::digits >= std::numeric_limits<int>::digits)
392    {
393       BOOST_CHECK_THROW(result = static_cast<T>(itrunc(static_cast<T>((std::numeric_limits<int>::max)()) + 1)), boost::math::rounding_error);
394       BOOST_CHECK_THROW(result = static_cast<T>(itrunc(static_cast<T>((std::numeric_limits<int>::min)()) - 1)), boost::math::rounding_error);
395    }
396    if (std::numeric_limits<T>::digits >= std::numeric_limits<long>::digits)
397    {
398       BOOST_CHECK_THROW(result = static_cast<T>(ltrunc(static_cast<T>((std::numeric_limits<long>::max)()) + 1)), boost::math::rounding_error);
399       BOOST_CHECK_THROW(result = static_cast<T>(ltrunc(static_cast<T>((std::numeric_limits<long>::min)()) - 1)), boost::math::rounding_error);
400    }
401 #ifndef BOOST_NO_LONG_LONG
402    if (std::numeric_limits<T>::digits >= std::numeric_limits<boost::long_long_type>::digits)
403    {
404       BOOST_CHECK_THROW(result = static_cast<T>(lltrunc(static_cast<T>((std::numeric_limits<boost::long_long_type>::max)()) + 1)), boost::math::rounding_error);
405       BOOST_CHECK_THROW(result = static_cast<T>(lltrunc(static_cast<T>((std::numeric_limits<boost::long_long_type>::min)()) - 1)), boost::math::rounding_error);
406    }
407 #endif
408    if (std::numeric_limits<T>::digits >= std::numeric_limits<int>::digits)
409    {
410       BOOST_CHECK_THROW(result = static_cast<T>(iround(static_cast<T>((std::numeric_limits<int>::max)()) + 1)), boost::math::rounding_error);
411       BOOST_CHECK_THROW(result = static_cast<T>(iround(static_cast<T>((std::numeric_limits<int>::min)()) - 1)), boost::math::rounding_error);
412    }
413    if (std::numeric_limits<T>::digits >= std::numeric_limits<long>::digits)
414    {
415       BOOST_CHECK_THROW(result = static_cast<T>(lround(static_cast<T>((std::numeric_limits<long>::max)()) + 1)), boost::math::rounding_error);
416       BOOST_CHECK_THROW(result = static_cast<T>(lround(static_cast<T>((std::numeric_limits<long>::min)()) - 1)), boost::math::rounding_error);
417    }
418 #ifndef BOOST_NO_LONG_LONG
419    if (std::numeric_limits<T>::digits >= std::numeric_limits<boost::long_long_type>::digits)
420    {
421       BOOST_CHECK_THROW(result = static_cast<T>(llround(static_cast<T>((std::numeric_limits<boost::long_long_type>::max)()) + 1)), boost::math::rounding_error);
422       BOOST_CHECK_THROW(result = static_cast<T>(llround(static_cast<T>((std::numeric_limits<boost::long_long_type>::min)()) - 1)), boost::math::rounding_error);
423    }
424 #endif
425 #endif
426 }
427
428 int main()
429 {
430 #ifdef TEST_MPF_50
431    test<boost::multiprecision::mpf_float_50>();
432    test<boost::multiprecision::mpf_float_100>();
433 #endif
434 #ifdef TEST_MPFR_50
435    test<boost::multiprecision::mpfr_float_50>();
436    test<boost::multiprecision::mpfr_float_100>();
437 #endif
438 #ifdef TEST_MPFI_50
439    test<boost::multiprecision::mpfi_float_50>();
440    test<boost::multiprecision::mpfi_float_100>();
441 #endif
442 #ifdef TEST_CPP_DEC_FLOAT
443    test<boost::multiprecision::cpp_dec_float_50>();
444    test<boost::multiprecision::cpp_dec_float_100>();
445 #ifndef SLOW_COMPLER
446    // Some "peculiar" digit counts which stress our code:
447    test<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<65> > >();
448    test<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<64> > >();
449    test<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<63> > >();
450    test<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<62> > >();
451    test<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<61, long long> > >();
452    test<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<60, long long> > >();
453    test<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<59, long long, std::allocator<char> > > >();
454    test<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<58, long long, std::allocator<char> > > >();
455 #endif
456 #endif
457 #ifdef TEST_CPP_BIN_FLOAT
458    test<boost::multiprecision::cpp_bin_float_50>();
459    test<boost::multiprecision::cpp_bin_float_100>();
460    test<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<35, boost::multiprecision::digit_base_10, std::allocator<char>, boost::long_long_type> > >();
461 #endif
462 #ifdef TEST_BACKEND
463    test<boost::multiprecision::number<boost::multiprecision::concepts::number_backend_float_architype> >();
464 #endif
465 #ifdef TEST_FLOAT128
466    test<boost::multiprecision::float128>();
467 #endif
468    return boost::report_errors();
469 }