Imported Upstream version 1.72.0
[platform/upstream/boost.git] / libs / multiprecision / test / test_numeric_limits.cpp
1 ///////////////////////////////////////////////////////////////
2 //  Copyright 2011 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 #ifdef _MSC_VER
7 #define _SCL_SECURE_NO_WARNINGS
8 #endif
9
10 #include "test.hpp"
11
12 #if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) &&         \
13     !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) && \
14     !defined(TEST_TOMMATH) && !defined(TEST_CPP_INT) && !defined(TEST_MPFI_50) && !defined(TEST_FLOAT128) && !defined(TEST_CPP_BIN_FLOAT)
15 #define TEST_MPF_50
16 #define TEST_MPF
17 #define TEST_BACKEND
18 #define TEST_MPZ
19 #define TEST_MPFR
20 #define TEST_MPFR_50
21 #define TEST_CPP_DEC_FLOAT
22 #define TEST_MPQ
23 #define TEST_TOMMATH
24 #define TEST_CPP_INT
25 #define TEST_MPFI_50
26 #define TEST_FLOAT128
27 #define TEST_CPP_BIN_FLOAT
28
29 #ifdef _MSC_VER
30 #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!")
31 #endif
32 #ifdef __GNUC__
33 #pragma warning "CAUTION!!: No backend type specified so testing everything.... this will take some time!!"
34 #endif
35
36 #endif
37
38 #if defined(TEST_MPF_50) || defined(TEST_MPF) || defined(TEST_MPZ) || defined(TEST_MPQ)
39 #include <boost/multiprecision/gmp.hpp>
40 #endif
41 #ifdef TEST_BACKEND
42 #include <boost/multiprecision/concepts/mp_number_archetypes.hpp>
43 #endif
44 #ifdef TEST_CPP_DEC_FLOAT
45 #include <boost/multiprecision/cpp_dec_float.hpp>
46 #endif
47 #if defined(TEST_MPFR) || defined(TEST_MPFR_50)
48 #include <boost/multiprecision/mpfr.hpp>
49 #endif
50 #if defined(TEST_MPFI_50)
51 #include <boost/multiprecision/mpfi.hpp>
52 #endif
53 #ifdef TEST_TOMMATH
54 #include <boost/multiprecision/tommath.hpp>
55 #endif
56 #ifdef TEST_CPP_INT
57 #include <boost/multiprecision/cpp_int.hpp>
58 #endif
59 #ifdef TEST_FLOAT128
60 #include <boost/multiprecision/float128.hpp>
61 #endif
62 #ifdef TEST_CPP_BIN_FLOAT
63 #include <boost/multiprecision/cpp_bin_float.hpp>
64 #endif
65
66 #ifdef BOOST_MSVC
67 #pragma warning(disable : 4127)
68 #endif
69
70 #define PRINT(x) \
71    std::cout << BOOST_STRINGIZE(x) << " = " << std::numeric_limits<Number>::x << std::endl;
72
73 template <class Number>
74 void test_specific(const boost::mpl::int_<boost::multiprecision::number_kind_floating_point>&)
75 {
76    Number minv, maxv;
77    minv = (std::numeric_limits<Number>::min)();
78    maxv = (std::numeric_limits<Number>::max)();
79    BOOST_CHECK((boost::math::isnormal)(minv));
80    BOOST_CHECK((boost::math::isnormal)(maxv));
81    BOOST_CHECK((boost::math::isnormal)(log(minv)));
82    BOOST_CHECK((boost::math::isnormal)(log(maxv)));
83    BOOST_CHECK((boost::math::isnormal)(sqrt(minv)));
84    BOOST_CHECK((boost::math::isnormal)(sqrt(maxv)));
85
86    if (std::numeric_limits<Number>::is_specialized)
87    {
88       if (std::numeric_limits<Number>::has_quiet_NaN)
89       {
90          BOOST_TEST((boost::math::isnan)(std::numeric_limits<Number>::quiet_NaN()));
91          BOOST_TEST(FP_NAN == (boost::math::fpclassify)(std::numeric_limits<Number>::quiet_NaN()));
92          BOOST_TEST(!(boost::math::isfinite)(std::numeric_limits<Number>::quiet_NaN()));
93          BOOST_TEST(!(boost::math::isnormal)(std::numeric_limits<Number>::quiet_NaN()));
94          BOOST_TEST(!(boost::math::isinf)(std::numeric_limits<Number>::quiet_NaN()));
95       }
96       if (std::numeric_limits<Number>::has_signaling_NaN)
97       {
98          BOOST_TEST((boost::math::isnan)(std::numeric_limits<Number>::signaling_NaN()));
99          BOOST_TEST(FP_NAN == (boost::math::fpclassify)(std::numeric_limits<Number>::signaling_NaN()));
100          BOOST_TEST(!(boost::math::isfinite)(std::numeric_limits<Number>::signaling_NaN()));
101          BOOST_TEST(!(boost::math::isnormal)(std::numeric_limits<Number>::signaling_NaN()));
102          BOOST_TEST(!(boost::math::isinf)(std::numeric_limits<Number>::signaling_NaN()));
103       }
104       if (std::numeric_limits<Number>::has_infinity)
105       {
106          BOOST_TEST((boost::math::isinf)(std::numeric_limits<Number>::infinity()));
107          BOOST_TEST(FP_INFINITE == (boost::math::fpclassify)(std::numeric_limits<Number>::infinity()));
108          BOOST_TEST(!(boost::math::isfinite)(std::numeric_limits<Number>::infinity()));
109          BOOST_TEST(!(boost::math::isnormal)(std::numeric_limits<Number>::infinity()));
110          BOOST_TEST(!(boost::math::isnan)(std::numeric_limits<Number>::infinity()));
111       }
112       if (std::numeric_limits<Number>::has_denorm == std::denorm_present)
113       {
114          BOOST_TEST(FP_SUBNORMAL == (boost::math::fpclassify)(std::numeric_limits<Number>::denorm_min()));
115          BOOST_TEST(FP_SUBNORMAL == (boost::math::fpclassify)((std::numeric_limits<Number>::min)() / 2));
116          BOOST_TEST((boost::math::isfinite)(std::numeric_limits<Number>::denorm_min()));
117          BOOST_TEST(!(boost::math::isnormal)(std::numeric_limits<Number>::denorm_min()));
118          BOOST_TEST(!(boost::math::isinf)(std::numeric_limits<Number>::denorm_min()));
119          BOOST_TEST(!(boost::math::isnan)(std::numeric_limits<Number>::denorm_min()));
120          BOOST_TEST(0 == std::numeric_limits<Number>::denorm_min() / 2);
121          BOOST_TEST(0 != (std::numeric_limits<Number>::min)() / 2);
122          BOOST_TEST(0 != std::numeric_limits<Number>::denorm_min());
123       }
124    }
125    Number n = 0;
126    BOOST_TEST((boost::math::fpclassify)(n) == FP_ZERO);
127    BOOST_TEST((boost::math::isfinite)(n));
128    BOOST_TEST(!(boost::math::isnormal)(n));
129    BOOST_TEST(!(boost::math::isinf)(n));
130    BOOST_TEST(!(boost::math::isnan)(n));
131    n = 2;
132    BOOST_TEST((boost::math::fpclassify)(n) == FP_NORMAL);
133    BOOST_TEST((boost::math::isfinite)(n));
134    BOOST_TEST((boost::math::isnormal)(n));
135    BOOST_TEST(!(boost::math::isinf)(n));
136    BOOST_TEST(!(boost::math::isnan)(n));
137
138    if (std::numeric_limits<Number>::round_style == std::round_to_nearest)
139    {
140       BOOST_CHECK_EQUAL(std::numeric_limits<Number>::round_error(), 0.5);
141    }
142    else if (std::numeric_limits<Number>::round_style != std::round_indeterminate)
143    {
144       // Round error is 1.0:
145       BOOST_CHECK_EQUAL(std::numeric_limits<Number>::round_error(), 1);
146    }
147    else
148    {
149       // Round error is presumably somewhere between 0.5 and 1:
150       BOOST_CHECK((std::numeric_limits<Number>::round_error() <= 1) && (std::numeric_limits<Number>::round_error() >= 0.5));
151    }
152 }
153
154 template <class Number>
155 void test_specific(const boost::mpl::int_<boost::multiprecision::number_kind_integer>&)
156 {
157    if (std::numeric_limits<Number>::is_modulo)
158    {
159       if (!std::numeric_limits<Number>::is_signed)
160       {
161          BOOST_TEST(1 + (std::numeric_limits<Number>::max)() == 0);
162          BOOST_TEST(--Number(0) == (std::numeric_limits<Number>::max)());
163       }
164    }
165 }
166
167 template <class Number, class T>
168 void test_specific(const T&)
169 {
170 }
171
172 template <class Number>
173 void test()
174 {
175    typedef typename boost::mpl::if_c<
176        std::numeric_limits<Number>::is_specialized,
177        typename boost::multiprecision::number_category<Number>::type,
178        boost::mpl::int_<500> // not a number type
179        >::type fp_test_type;
180
181    test_specific<Number>(fp_test_type());
182
183    //
184    // Note really a test just yet, but we can at least print out all the values:
185    //
186    std::cout << "numeric_limits values for type " << typeid(Number).name() << std::endl;
187
188    PRINT(is_specialized);
189    if (std::numeric_limits<Number>::is_integer)
190    {
191       std::cout << std::hex << std::showbase;
192    }
193    std::cout << "max()"
194              << " = " << (std::numeric_limits<Number>::max)() << std::endl;
195    if (std::numeric_limits<Number>::is_integer)
196    {
197       std::cout << std::dec;
198    }
199    std::cout << "max()"
200              << " = " << (std::numeric_limits<Number>::max)() << std::endl;
201    std::cout << "min()"
202              << " = " << (std::numeric_limits<Number>::min)() << std::endl;
203 #ifndef BOOST_NO_CXX11_NUMERIC_LIMITS
204    PRINT(lowest());
205 #endif
206    PRINT(digits);
207    PRINT(digits10);
208 #ifndef BOOST_NO_CXX11_NUMERIC_LIMITS
209    PRINT(max_digits10);
210 #endif
211    PRINT(is_signed);
212    PRINT(is_integer);
213    PRINT(is_exact);
214    PRINT(radix);
215    PRINT(epsilon());
216    PRINT(round_error());
217    PRINT(min_exponent);
218    PRINT(min_exponent10);
219    PRINT(max_exponent);
220    PRINT(max_exponent10);
221    PRINT(has_infinity);
222    PRINT(has_quiet_NaN);
223    PRINT(has_signaling_NaN);
224    PRINT(has_denorm);
225    PRINT(has_denorm_loss);
226    PRINT(infinity());
227    PRINT(quiet_NaN());
228    PRINT(signaling_NaN());
229    PRINT(denorm_min());
230    PRINT(is_iec559);
231    PRINT(is_bounded);
232    PRINT(is_modulo);
233    PRINT(traps);
234    PRINT(tinyness_before);
235    PRINT(round_style);
236 }
237
238 int main()
239 {
240 #ifdef TEST_BACKEND
241    test<boost::multiprecision::number<boost::multiprecision::concepts::number_backend_float_architype> >();
242 #endif
243 #ifdef TEST_MPF_50
244    test<boost::multiprecision::mpf_float_50>();
245 #endif
246 #ifdef TEST_MPF
247    boost::multiprecision::mpf_float::default_precision(1000);
248    /*
249    boost::multiprecision::mpf_float r;
250    r.precision(50);
251    BOOST_TEST(r.precision() >= 50);
252    */
253    BOOST_TEST(boost::multiprecision::mpf_float::default_precision() == 1000);
254    test<boost::multiprecision::mpf_float>();
255 #endif
256 #ifdef TEST_MPZ
257    test<boost::multiprecision::mpz_int>();
258 #endif
259 #ifdef TEST_MPQ
260    test<boost::multiprecision::mpq_rational>();
261 #endif
262 #ifdef TEST_CPP_DEC_FLOAT
263    test<boost::multiprecision::cpp_dec_float_50>();
264    test<boost::multiprecision::cpp_dec_float_100>();
265 #endif
266 #ifdef TEST_MPFR
267    test<boost::multiprecision::mpfr_float>();
268 #endif
269 #ifdef TEST_MPFR_50
270    test<boost::multiprecision::mpfr_float_50>();
271 #endif
272 #ifdef TEST_MPFI_50
273    test<boost::multiprecision::mpfi_float_50>();
274    test<boost::multiprecision::mpfi_float>();
275 #endif
276 #ifdef TEST_TOMMATH
277    test<boost::multiprecision::tom_int>();
278 #endif
279 #ifdef TEST_CPP_INT
280    test<boost::multiprecision::cpp_int>();
281    test<boost::multiprecision::int256_t>();
282    test<boost::multiprecision::uint512_t>();
283    test<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<200, 200, boost::multiprecision::unsigned_magnitude, boost::multiprecision::checked, void> > >();
284    test<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<70, 70, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void> > >();
285 #endif
286 #ifdef TEST_FLOAT128
287    test<boost::multiprecision::float128>();
288 #endif
289 #ifdef TEST_CPP_BIN_FLOAT
290    test<boost::multiprecision::cpp_bin_float_50>();
291 #endif
292    return boost::report_errors();
293 }