Imported Upstream version 1.72.0
[platform/upstream/boost.git] / libs / math / test / test_cstdfloat.cpp
1 //  Copyright Christopher Kormanyos 2014.
2 //  Copyright John Maddock 2014.
3 //  Copyright Paul A. Bristow 2014.
4
5 //  Use, modification and distribution are subject to the
6 //  Boost Software License, Version 1.0. (See accompanying file
7 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8
9 #include <cmath>
10 #include <complex>
11 #include <limits>
12 #include <iostream>
13 #include <iomanip>
14 #include <sstream>
15 #include <string>
16 #include <boost/cstdfloat.hpp>
17
18 #ifdef _MSC_VER
19 #  pragma warning(disable : 4127) // conditional expression is constant.
20 #  pragma warning(disable : 4512) // assignment operator could not be generated.
21 #  pragma warning(disable : 4996) // use -D_SCL_SECURE_NO_WARNINGS.
22 #endif
23
24 #define BOOST_TEST_MAIN
25 #include <boost/test/unit_test.hpp> // Boost.Test
26 #include <boost/test/tools/floating_point_comparison.hpp>
27 #include <boost/scoped_array.hpp>
28
29 //
30 // We need to define an iostream operator for __float128 in order to
31 // compile this test:
32 //
33
34 //
35 // DESCRIPTION:
36 // ~~~~~~~~~~~~
37 //
38 // This file tests the implementation of floating-point typedefs having
39 // specified widths, as implemented in <boost/cstdfloat.hpp> and described
40 // in N3626 (proposed for C++14).
41
42 // For more information on <boost/cstdfloat.hpp> and the corresponding
43 // proposal of "Floating-Point Typedefs Having Specified Widths",
44 // see: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3626.pdf
45
46 // The tests:
47 //
48 // Perform sanity checks on boost::float16_t, boost::float32_t,
49 // boost::float64_t, boost::float80_t, and boost::float128_t when
50 // these types are available. In the sanity checks, we verify the
51 // formal behavior of the types and the macros for creating literal
52 // floating-point constants.
53 //
54 // An extended check is included for boost::float128_t. This checks
55 // the functionality of <cmath>, I/O stream operations, and <complex>
56 // functions for boost::float128_t.
57
58 // For some reason the (x != x) check fails on Mingw:
59 #if !defined(__MINGW64__)
60 #define TEST_CSTDFLOAT_SANITY_CHECK_NAN(the_digits)                                                  \
61   {                                                                                                  \
62     using std::sqrt;                                                                                 \
63     const float_type x = sqrt(float_type(test_cstdfloat::minus_one));                                \
64     const bool the_nan_test = (   std::numeric_limits<float_type>::has_quiet_NaN                     \
65                                && (x != x));                                                         \
66     BOOST_CHECK_EQUAL( the_nan_test, true );                                                         \
67   }  
68 #else
69 #define TEST_CSTDFLOAT_SANITY_CHECK_NAN(the_digits)                                                  
70 #endif
71
72 #define TEST_CSTDFLOAT_SANITY_CHECK(the_digits)                                                      \
73 void sanity_check_##the_digits##_func()                                                              \
74 {                                                                                                    \
75   typedef boost::float##the_digits##_t float_type;                                                   \
76                                                                                                      \
77   BOOST_CONSTEXPR_OR_CONST int my_digits10 = std::numeric_limits<float_type>::digits10;              \
78                                                                                                      \
79   {                                                                                                  \
80     BOOST_CONSTEXPR_OR_CONST float_type x =                                                          \
81       BOOST_FLOAT##the_digits##_C(0.33333333333333333333333333333333333333333);                      \
82     std::stringstream ss;                                                                            \
83     ss << std::setprecision(my_digits10 - 1)                                                         \
84        << x;                                                                                         \
85     std::string str = "0.";                                                                          \
86     str += std::string(std::string::size_type(my_digits10 - 1), char('3'));                          \
87     BOOST_CHECK_EQUAL( ss.str(), str );                                                              \
88   }                                                                                                  \
89   {                                                                                                  \
90     BOOST_CONSTEXPR_OR_CONST float_type x =                                                          \
91       BOOST_FLOAT##the_digits##_C(0.66666666666666666666666666666666666666666);                      \
92     std::stringstream ss;                                                                            \
93     ss << std::setprecision(my_digits10 - 1)                                                         \
94        << x;                                                                                         \
95     std::string str = "0.";                                                                          \
96     str += std::string(std::string::size_type(my_digits10 - 2), char('6'));                          \
97     str += "7";                                                                                      \
98     BOOST_CHECK_EQUAL( ss.str(), str );                                                              \
99   }                                                                                                  \
100   {                                                                                                  \
101     const float_type x = BOOST_FLOAT##the_digits##_C(1.0) / test_cstdfloat::zero;                    \
102     const bool the_inf_test = (   std::numeric_limits<float_type>::has_infinity                      \
103                                && (x == std::numeric_limits<float_type>::infinity()));               \
104     BOOST_CHECK_EQUAL( the_inf_test, true );                                                         \
105   }                                                                                                  \
106   TEST_CSTDFLOAT_SANITY_CHECK_NAN(the_digits)\
107   {                                                                                                  \
108     const bool the_lim_test =                                                                        \
109       (std::numeric_limits<boost::floatmax_t>::digits >= std::numeric_limits<float_type>::digits);   \
110     BOOST_CHECK_EQUAL( the_lim_test, true );                                                         \
111   }                                                                                                  \
112 }
113
114 namespace test_cstdfloat
115 {
116 #if defined(BOOST_FLOAT128_C)
117
118    template <class T, class U>
119    void test_less(T a, U b)
120    {
121       BOOST_CHECK(a < b);
122       BOOST_CHECK(a <= b);
123       BOOST_CHECK(!(a > b));
124       BOOST_CHECK(!(a >= b));
125       BOOST_CHECK(!(a == b));
126       BOOST_CHECK((a != b));
127
128       BOOST_CHECK(b > a);
129       BOOST_CHECK(b >= a);
130       BOOST_CHECK(!(b < a));
131       BOOST_CHECK(!(b <= a));
132       BOOST_CHECK(!(b == a));
133       BOOST_CHECK((b != a));
134
135       BOOST_CHECK(std::isless(a, b));
136       BOOST_CHECK(std::islessequal(a, b));
137       BOOST_CHECK(!std::isgreater(a, b));
138       BOOST_CHECK(!std::isgreaterequal(a, b));
139       BOOST_CHECK(std::islessgreater(a, b));
140
141       BOOST_CHECK(!std::isless(b, a));
142       BOOST_CHECK(!std::islessequal(b, a));
143       BOOST_CHECK(std::isgreater(b, a));
144       BOOST_CHECK(std::isgreaterequal(b, a));
145       BOOST_CHECK(std::islessgreater(b, a));
146    }
147    template <class T, class U>
148    void test_equal(T a, U b)
149    {
150       BOOST_CHECK(!(a < b));
151       BOOST_CHECK(a <= b);
152       BOOST_CHECK(!(a > b));
153       BOOST_CHECK((a >= b));
154       BOOST_CHECK((a == b));
155       BOOST_CHECK(!(a != b));
156
157       BOOST_CHECK(!(b > a));
158       BOOST_CHECK(b >= a);
159       BOOST_CHECK(!(b < a));
160       BOOST_CHECK((b <= a));
161       BOOST_CHECK((b == a));
162       BOOST_CHECK(!(b != a));
163
164       BOOST_CHECK(!std::isless(a, b));
165       BOOST_CHECK(std::islessequal(a, b));
166       BOOST_CHECK(!std::isgreater(a, b));
167       BOOST_CHECK(std::isgreaterequal(a, b));
168       BOOST_CHECK(!std::islessgreater(a, b));
169
170       BOOST_CHECK(!std::isless(b, a));
171       BOOST_CHECK(std::islessequal(b, a));
172       BOOST_CHECK(!std::isgreater(b, a));
173       BOOST_CHECK(std::isgreaterequal(b, a));
174       BOOST_CHECK(!std::islessgreater(b, a));
175    }
176    template <class T, class U>
177    void test_unordered(T a, U b)
178    {
179       BOOST_CHECK(!(a < b));
180       BOOST_CHECK(!(a <= b));
181       BOOST_CHECK(!(a > b));
182       BOOST_CHECK(!(a >= b));
183       BOOST_CHECK(!(a == b));
184       BOOST_CHECK((a != b));
185
186       BOOST_CHECK(!(b > a));
187       BOOST_CHECK(!(b >= a));
188       BOOST_CHECK(!(b < a));
189       BOOST_CHECK(!(b <= a));
190       BOOST_CHECK(!(b == a));
191       BOOST_CHECK((b != a));
192
193       BOOST_CHECK(!std::isless(a, b));
194       BOOST_CHECK(!std::islessequal(a, b));
195       BOOST_CHECK(!std::isgreater(a, b));
196       BOOST_CHECK(!std::isgreaterequal(a, b));
197       BOOST_CHECK(!std::islessgreater(a, b));
198
199       BOOST_CHECK(!std::isless(b, a));
200       BOOST_CHECK(!std::islessequal(b, a));
201       BOOST_CHECK(!std::isgreater(b, a));
202       BOOST_CHECK(!std::isgreaterequal(b, a));
203       BOOST_CHECK(!std::islessgreater(b, a));
204    }
205
206    template <class T>
207    void test()
208    {
209       //
210       // Basic sanity checks for C99 functions which are just imported versions
211       // from Boost.Math.  These should still be found via ADL so no using declarations here...
212       //
213       T val = 2;
214       BOOST_CHECK(std::signbit(val) == 0);
215       BOOST_CHECK(std::signbit(val + 2) == 0);
216       val = -val;
217       BOOST_CHECK(std::signbit(val));
218       BOOST_CHECK(std::signbit(val * 2));
219
220       T s = 2;
221       val = 3;
222       BOOST_CHECK_EQUAL(std::copysign(val, s), 3);
223       BOOST_CHECK_EQUAL(std::copysign(val, s * -2), -3);
224       BOOST_CHECK_EQUAL(std::copysign(-2 * val, s), 6);
225       BOOST_CHECK_EQUAL(std::copysign(-2 * val, 2 * s), 6);
226       s = -2;
227       BOOST_CHECK_EQUAL(std::copysign(val, s), -3);
228       BOOST_CHECK_EQUAL(std::copysign(val, s * -2), 3);
229       BOOST_CHECK_EQUAL(std::copysign(-2 * val, s), -6);
230       BOOST_CHECK_EQUAL(std::copysign(-2 * val, 2 * s), -6);
231       val = -3;
232       BOOST_CHECK_EQUAL(std::copysign(val, s), -3);
233       BOOST_CHECK_EQUAL(std::copysign(val, s * -2), 3);
234       BOOST_CHECK_EQUAL(std::copysign(-2 * val, s), -6);
235       BOOST_CHECK_EQUAL(std::copysign(-2 * val, 2 * s), -6);
236       s = 0;
237       BOOST_CHECK_EQUAL(std::copysign(val, s), 3);
238       BOOST_CHECK_EQUAL(std::copysign(val, s * -2), -3);
239
240       BOOST_CHECK_EQUAL(std::copysign(-2 * val, s), 6);
241       BOOST_CHECK_EQUAL(std::copysign(-2 * val, 2 * s), 6);
242       // Things involving signed zero, need to detect it first:
243
244       val = 3;
245       BOOST_CHECK_EQUAL(std::fpclassify(val), FP_NORMAL);
246       BOOST_CHECK_EQUAL(std::fpclassify(val * 3), FP_NORMAL);
247       BOOST_CHECK(!std::isinf(val));
248       BOOST_CHECK(!std::isinf(val + 2));
249       BOOST_CHECK(!std::isnan(val));
250       BOOST_CHECK(!std::isnan(val + 2));
251       BOOST_CHECK(std::isnormal(val));
252       BOOST_CHECK(std::isnormal(val + 2));
253       val = -3;
254       BOOST_CHECK_EQUAL(std::fpclassify(val), FP_NORMAL);
255       BOOST_CHECK_EQUAL(std::fpclassify(val * 3), FP_NORMAL);
256       BOOST_CHECK(!std::isinf(val));
257       BOOST_CHECK(!std::isinf(val + 2));
258       BOOST_CHECK(!std::isnan(val));
259       BOOST_CHECK(!std::isnan(val + 2));
260       BOOST_CHECK(std::isnormal(val));
261       BOOST_CHECK(std::isnormal(val + 2));
262       val = 0;
263       BOOST_CHECK_EQUAL(std::fpclassify(val), FP_ZERO);
264       BOOST_CHECK_EQUAL(std::fpclassify(val * 3), FP_ZERO);
265       BOOST_CHECK(!std::isinf(val));
266       BOOST_CHECK(!std::isinf(val + 2));
267       BOOST_CHECK(!std::isnan(val));
268       BOOST_CHECK(!std::isnan(val + 2));
269       BOOST_CHECK(!std::isnormal(val));
270       BOOST_CHECK(!std::isnormal(val * 2));
271       BOOST_CHECK(!std::isnormal(val * -2));
272       if (std::numeric_limits<T>::has_infinity)
273       {
274          val = std::numeric_limits<T>::infinity();
275          BOOST_CHECK_EQUAL(std::fpclassify(val), FP_INFINITE);
276          BOOST_CHECK_EQUAL(std::fpclassify(val * 3), FP_INFINITE);
277          BOOST_CHECK(std::isinf(val));
278          BOOST_CHECK(std::isinf(val + 2));
279          BOOST_CHECK(!std::isnan(val));
280          BOOST_CHECK(!std::isnan(val + 2));
281          BOOST_CHECK(!std::isnormal(val));
282          BOOST_CHECK(!std::isnormal(val + 2));
283          val = -val;
284          BOOST_CHECK_EQUAL(std::fpclassify(val), FP_INFINITE);
285          BOOST_CHECK_EQUAL(std::fpclassify(val * 3), FP_INFINITE);
286          BOOST_CHECK(std::isinf(val));
287          BOOST_CHECK(std::isinf(val + 2));
288          BOOST_CHECK(!std::isnan(val));
289          BOOST_CHECK(!std::isnan(val + 2));
290          BOOST_CHECK(!std::isnormal(val));
291          BOOST_CHECK(!std::isnormal(val + 2));
292       }
293       if (std::numeric_limits<T>::has_quiet_NaN)
294       {
295          val = std::numeric_limits <T>::quiet_NaN();
296          BOOST_CHECK_EQUAL(std::fpclassify(val), FP_NAN);
297          BOOST_CHECK_EQUAL(std::fpclassify(val * 3), FP_NAN);
298          BOOST_CHECK(!std::isinf(val));
299          BOOST_CHECK(!std::isinf(val + 2));
300          BOOST_CHECK(std::isnan(val));
301          BOOST_CHECK(std::isnan(val + 2));
302          BOOST_CHECK(!std::isnormal(val));
303          BOOST_CHECK(!std::isnormal(val + 2));
304       }
305       s = 8 * std::numeric_limits<T>::epsilon();
306       val = 2.5;
307       BOOST_CHECK_CLOSE_FRACTION(std::asinh(val), T(1.6472311463710957106248586104436196635044144301932365282203100930843983757633104078778420255069424907777006132075516484778755360595913172299093829522950397895699619540523579875476513967578478619028438291006578604823887119907434Q), s);
308       BOOST_CHECK_CLOSE_FRACTION(std::acosh(val), T(1.5667992369724110786640568625804834938620823510926588639329459980122148134693922696279968499622201141051039184050936311066453565386393240356562374302417843319480223211857615778787272615171906055455922537080327062362258846337050Q), s);
309       val = 0.5;
310       BOOST_CHECK_CLOSE_FRACTION(std::atanh(val), T(0.5493061443340548456976226184612628523237452789113747258673471668187471466093044834368078774068660443939850145329789328711840021129652599105264009353836387053015813845916906835896868494221804799518712851583979557605727959588753Q), s);
311       val = 55.25;
312       BOOST_CHECK_CLOSE_FRACTION(std::cbrt(val), T(3.8087058015466360309383876359583281382991983919300128125378938779672144843676192684301168479657279498120767424724024965319869248797423276064015643361426189576415670917818313417529572608229017809069355688606687557031643655896118Q), s);
313       val = 2.75;
314       BOOST_CHECK_CLOSE_FRACTION(std::erf(val), T(0.9998993780778803631630956080249130432349352621422640655161095794654526422025908961447328296681056892975214344779300734620255391682713519265048496199034963706976420982849598189071465666866369396765001072187538732800143945532487Q), s);
315       BOOST_CHECK_CLOSE_FRACTION(std::erfc(val), T(0.0001006219221196368369043919750869567650647378577359344838904205345473577974091038552671703318943107024785655220699265379744608317286480734951503800965036293023579017150401810928534333133630603234998927812461267199856054467512Q), s);
316       val = 0.125;
317       BOOST_CHECK_CLOSE_FRACTION(std::expm1(val), T(0.1331484530668263168290072278117938725655031317451816259128200360788235778800483865139399907949417285732315270156473075657048210452584733998785564025916995261162759280700397984729320345630340659469435372721057879969170503978449Q), s);
318
319       val = 20;
320       s = 2;
321       BOOST_CHECK_EQUAL(std::fdim(val, s), 18);
322       BOOST_CHECK_EQUAL(std::fdim(s, val), 0);
323       BOOST_CHECK_EQUAL(std::fdim(val, s * 2), 16);
324       BOOST_CHECK_EQUAL(std::fdim(s * 2, val), 0);
325       BOOST_CHECK_EQUAL(std::fdim(val, 2), 18);
326       BOOST_CHECK_EQUAL(std::fdim(2, val), 0);
327
328       BOOST_CHECK_EQUAL(std::fmax(val, s), val);
329       BOOST_CHECK_EQUAL(std::fmax(s, val), val);
330       BOOST_CHECK_EQUAL(std::fmax(val * 2, s), val * 2);
331       BOOST_CHECK_EQUAL(std::fmax(val, s * 2), val);
332       BOOST_CHECK_EQUAL(std::fmax(val * 2, s * 2), val * 2);
333       BOOST_CHECK_EQUAL(std::fmin(val, s), s);
334       BOOST_CHECK_EQUAL(std::fmin(s, val), s);
335       BOOST_CHECK_EQUAL(std::fmin(val * 2, s), s);
336       BOOST_CHECK_EQUAL(std::fmin(val, s * 2), s * 2);
337       BOOST_CHECK_EQUAL(std::fmin(val * 2, s * 2), s * 2);
338
339       BOOST_CHECK_EQUAL(std::fmax(val, 2), val);
340       BOOST_CHECK_EQUAL(std::fmax(val, 2.0), val);
341       BOOST_CHECK_EQUAL(std::fmax(20, s), val);
342       BOOST_CHECK_EQUAL(std::fmax(20.0, s), val);
343       BOOST_CHECK_EQUAL(std::fmin(val, 2), s);
344       BOOST_CHECK_EQUAL(std::fmin(val, 2.0), s);
345       BOOST_CHECK_EQUAL(std::fmin(20, s), s);
346       BOOST_CHECK_EQUAL(std::fmin(20.0, s), s);
347       if (std::numeric_limits<T>::has_quiet_NaN)
348       {
349          BOOST_CHECK_EQUAL(std::fmax(val, std::numeric_limits<T>::quiet_NaN()), val);
350          BOOST_CHECK_EQUAL(std::fmax(std::numeric_limits<T>::quiet_NaN(), val), val);
351          BOOST_CHECK_EQUAL(std::fmin(val, std::numeric_limits<T>::quiet_NaN()), val);
352          BOOST_CHECK_EQUAL(std::fmin(std::numeric_limits<T>::quiet_NaN(), val), val);
353       }
354       if (std::numeric_limits<double>::has_quiet_NaN)
355       {
356          BOOST_CHECK_EQUAL(std::fmax(val, std::numeric_limits<double>::quiet_NaN()), val);
357          BOOST_CHECK_EQUAL(std::fmax(std::numeric_limits<double>::quiet_NaN(), val), val);
358          BOOST_CHECK_EQUAL(std::fmin(val, std::numeric_limits<double>::quiet_NaN()), val);
359          BOOST_CHECK_EQUAL(std::fmin(std::numeric_limits<double>::quiet_NaN(), val), val);
360       }
361
362       test_less(s, val);
363       test_less(2, val);
364       test_less(s, 20);
365       test_less(s + 0, val);
366       test_less(s, val * 1);
367       test_less(s * 1, val * 1);
368       test_less(s * 1, 20);
369       test_less(s + 2, val * 2);
370
371       test_equal(val, val);
372       test_equal(20, val);
373       test_equal(val, 20);
374       test_equal(val + 0, val);
375       test_equal(val, val * 1);
376       test_equal(val * 1, val * 1);
377       test_equal(val * 1, 20);
378       test_equal(val * 20, val * 20);
379
380       if (std::numeric_limits<T>::has_quiet_NaN)
381       {
382          s = std::numeric_limits<T>::quiet_NaN();
383          test_unordered(s, val);
384          test_unordered(s, 20);
385          test_unordered(s + 0, val);
386          test_unordered(s, val * 1);
387          test_unordered(s * 1, val * 1);
388          test_unordered(s * 1, 20);
389          test_unordered(s + 2, val * 2);
390          if (std::numeric_limits<double>::has_quiet_NaN)
391          {
392             double n = std::numeric_limits<double>::quiet_NaN();
393             test_unordered(n, val);
394          }
395       }
396
397       T tol = 8 * std::numeric_limits<T>::epsilon();
398       s = 2;
399       BOOST_CHECK_CLOSE_FRACTION(T(std::hypot(val, s)), T(20.099751242241780540438529825519152373890046940052754581145656594656982463103940762472355384907904704732599006530Q), tol);
400       BOOST_CHECK_CLOSE_FRACTION(T(std::hypot(val, 2)), T(20.099751242241780540438529825519152373890046940052754581145656594656982463103940762472355384907904704732599006530Q), tol);
401       BOOST_CHECK_CLOSE_FRACTION(T(std::hypot(val, 2.0)), T(20.099751242241780540438529825519152373890046940052754581145656594656982463103940762472355384907904704732599006530Q), tol);
402       BOOST_CHECK_CLOSE_FRACTION(T(std::hypot(20, s)), T(20.099751242241780540438529825519152373890046940052754581145656594656982463103940762472355384907904704732599006530Q), tol);
403       BOOST_CHECK_CLOSE_FRACTION(T(std::hypot(20.0, s)), T(20.099751242241780540438529825519152373890046940052754581145656594656982463103940762472355384907904704732599006530Q), tol);
404       BOOST_CHECK_CLOSE_FRACTION(T(std::hypot(val * 1, s)), T(20.099751242241780540438529825519152373890046940052754581145656594656982463103940762472355384907904704732599006530Q), tol);
405       BOOST_CHECK_CLOSE_FRACTION(T(std::hypot(val * 1, s * 1)), T(20.099751242241780540438529825519152373890046940052754581145656594656982463103940762472355384907904704732599006530Q), tol);
406       BOOST_CHECK_CLOSE_FRACTION(T(std::hypot(val * 1, 2)), T(20.099751242241780540438529825519152373890046940052754581145656594656982463103940762472355384907904704732599006530Q), tol);
407       BOOST_CHECK_CLOSE_FRACTION(T(std::hypot(val * 1, 2.0)), T(20.099751242241780540438529825519152373890046940052754581145656594656982463103940762472355384907904704732599006530Q), tol);
408       BOOST_CHECK_CLOSE_FRACTION(T(std::hypot(20, s * 1)), T(20.099751242241780540438529825519152373890046940052754581145656594656982463103940762472355384907904704732599006530Q), tol);
409       BOOST_CHECK_CLOSE_FRACTION(T(std::hypot(20.0, s * 1)), T(20.099751242241780540438529825519152373890046940052754581145656594656982463103940762472355384907904704732599006530Q), tol);
410
411       BOOST_CHECK_CLOSE_FRACTION(std::lgamma(val), T(39.339884187199494036224652394567381081691457206897853119937969989377572554993874476249340525204204720861169039582Q), tol);
412       BOOST_CHECK_CLOSE_FRACTION(std::lgamma(val + 0), T(39.339884187199494036224652394567381081691457206897853119937969989377572554993874476249340525204204720861169039582Q), tol);
413
414       BOOST_CHECK_EQUAL(std::lrint(val), 20);
415       BOOST_CHECK_EQUAL(std::lrint(val * 2), 40);
416       BOOST_CHECK_EQUAL(std::llrint(val), 20);
417       BOOST_CHECK_EQUAL(std::llrint(val * 2), 40);
418
419       val = 0.125;
420       BOOST_CHECK_CLOSE_FRACTION(std::log1p(val), T(0.117783035656383454538794109470521705068480712564733141107348638794807720528133786929641528638208114949935615070Q), tol);
421       BOOST_CHECK_CLOSE_FRACTION(std::log1p(val + 0), T(0.117783035656383454538794109470521705068480712564733141107348638794807720528133786929641528638208114949935615070Q), tol);
422       val = 20;
423       BOOST_CHECK_CLOSE_FRACTION(T(std::log2(val)), T(4.321928094887362347870319429489390175864831393024580612054756395815934776608625215850139743359370155099657371710Q), tol);
424       BOOST_CHECK_CLOSE_FRACTION(T(std::log2(val + 0)), T(4.321928094887362347870319429489390175864831393024580612054756395815934776608625215850139743359370155099657371710Q), tol);
425
426       BOOST_CHECK_EQUAL(T(std::nearbyint(val)), 20);
427       BOOST_CHECK_EQUAL(T(std::nearbyint(val + 0.25)), 20);
428       BOOST_CHECK_EQUAL(T(std::rint(val)), 20);
429       BOOST_CHECK_EQUAL(T(std::rint(val + 0.25)), 20);
430
431       BOOST_CHECK_GT(std::nextafter(val, T(200)), val);
432       BOOST_CHECK_GT(std::nextafter(val + 0, T(200)), val);
433       BOOST_CHECK_GT(std::nextafter(val + 0, T(200) + 1), val);
434       BOOST_CHECK_GT(std::nextafter(val, T(200) + 1), val);
435
436       BOOST_CHECK_GT(std::nexttoward(val, T(200)), val);
437       BOOST_CHECK_GT(std::nexttoward(val + 0, T(200)), val);
438       BOOST_CHECK_GT(std::nexttoward(val + 0, T(200) + 1), val);
439       BOOST_CHECK_GT(std::nexttoward(val, T(200) + 1), val);
440
441       val = 21;
442       s = 5;
443       BOOST_CHECK_EQUAL(T(std::remainder(val, s)), 1);
444       BOOST_CHECK_EQUAL(T(std::remainder(val, 5)), 1);
445       BOOST_CHECK_EQUAL(T(std::remainder(21, s)), 1);
446       BOOST_CHECK_EQUAL(T(std::remainder(val * 1, s)), 1);
447       BOOST_CHECK_EQUAL(T(std::remainder(val * 1, s * 1)), 1);
448       BOOST_CHECK_EQUAL(T(std::remainder(val, s * 1)), 1);
449       BOOST_CHECK_EQUAL(T(std::remainder(val * 1, 5)), 1);
450       BOOST_CHECK_EQUAL(T(std::remainder(21, s * 1)), 1);
451       int i(0);
452       BOOST_CHECK_EQUAL(T(std::remquo(val, s, &i)), 1);
453       BOOST_CHECK_EQUAL(i, 4);
454       i = 0;
455       BOOST_CHECK_EQUAL(T(std::remquo(val, 5, &i)), 1);
456       BOOST_CHECK_EQUAL(i, 4);
457       i = 0;
458       BOOST_CHECK_EQUAL(T(std::remquo(21, s, &i)), 1);
459       BOOST_CHECK_EQUAL(i, 4);
460       i = 0;
461       BOOST_CHECK_EQUAL(T(std::remquo(val * 1, s, &i)), 1);
462       BOOST_CHECK_EQUAL(i, 4);
463       i = 0;
464       BOOST_CHECK_EQUAL(T(std::remquo(val * 1, s * 1, &i)), 1);
465       BOOST_CHECK_EQUAL(i, 4);
466       i = 0;
467       BOOST_CHECK_EQUAL(T(std::remquo(val, s * 1, &i)), 1);
468       BOOST_CHECK_EQUAL(i, 4);
469       i = 0;
470       BOOST_CHECK_EQUAL(T(std::remquo(val * 1, 5, &i)), 1);
471       BOOST_CHECK_EQUAL(i, 4);
472       i = 0;
473       BOOST_CHECK_EQUAL(T(std::remquo(21, s * 1, &i)), 1);
474       BOOST_CHECK_EQUAL(i, 4);
475       i = 0;
476       val = 5.25;
477       tol = 3000;
478       BOOST_CHECK_CLOSE_FRACTION(std::tgamma(val), T(35.211611852799685705225257690531248115026311138908448314086859575901217653313145619623624570033258659272301335544Q), tol);
479       BOOST_CHECK_CLOSE_FRACTION(std::tgamma(val + 1), T(184.86096222719834995243260287528905260388813347926935364895601277348139267989401450302402899267460796117958201160Q), tol);
480
481       BOOST_CHECK_CLOSE_FRACTION(T(std::exp2(val)), T(38.054627680087074134959999057935229289375106958842157216608071191022933383261349115865003025220405558913196632792Q), tol);
482       BOOST_CHECK_CLOSE_FRACTION(T(std::exp2(val + 1)), T(76.109255360174148269919998115870458578750213917684314433216142382045866766522698231730006050440811117826393265585Q), tol);
483       val = 15;
484       BOOST_CHECK_CLOSE_FRACTION(T(std::exp2(val)), T(32768uL), tol);
485       BOOST_CHECK_CLOSE_FRACTION(T(std::exp2(val + 1)), T(65536uL), tol);
486
487       i = std::fpclassify(val) + std::isgreaterequal(val, s) + std::islessequal(val, s) + std::isnan(val) + std::isunordered(val, s)
488          + std::isfinite(val) + std::isinf(val) + std::islessgreater(val, s) + std::isnormal(val) + std::signbit(val) + std::isgreater(val, s) + std::isless(val, s);
489    }
490
491 #endif
492
493    int zero;
494    int minus_one;
495
496 #if defined(BOOST_FLOATMAX_C)
497    BOOST_CONSTEXPR_OR_CONST int has_floatmax_t = 1;
498 #else
499    BOOST_CONSTEXPR_OR_CONST int has_floatmax_t = 0;
500 #endif
501
502 #if defined(BOOST_FLOAT16_C)
503    TEST_CSTDFLOAT_SANITY_CHECK(16)
504 #endif
505
506 #if defined(BOOST_FLOAT32_C)
507       TEST_CSTDFLOAT_SANITY_CHECK(32)
508 #endif
509
510 #if defined(BOOST_FLOAT64_C)
511       TEST_CSTDFLOAT_SANITY_CHECK(64)
512 #endif
513
514 #if defined(BOOST_FLOAT80_C)
515       TEST_CSTDFLOAT_SANITY_CHECK(80)
516 #endif
517
518 #if defined(BOOST_FLOAT128_C)
519       TEST_CSTDFLOAT_SANITY_CHECK(128)
520
521       void extend_check_128_func()
522    {
523       test<boost::float128_t>();
524    }
525 #endif // defined (BOOST_FLOAT128_C)
526 }
527
528 BOOST_AUTO_TEST_CASE(test_main)
529 {
530    test_cstdfloat::zero = 0;
531    test_cstdfloat::minus_one = -1;
532
533    // Perform basic sanity checks that verify both the existence of the proper
534    // floating-point literal macros as well as the correct digit handling
535    // for a given floating-point typedef having specified width.
536
537    BOOST_CHECK_EQUAL(test_cstdfloat::has_floatmax_t, 1);
538
539 #if defined(BOOST_FLOAT16_C)
540    test_cstdfloat::sanity_check_16_func();
541 #endif
542
543 #if defined(BOOST_FLOAT32_C)
544    test_cstdfloat::sanity_check_32_func();
545 #endif
546
547 #if defined(BOOST_FLOAT64_C)
548    test_cstdfloat::sanity_check_64_func();
549 #endif
550
551 #if defined(BOOST_FLOAT80_C)
552    test_cstdfloat::sanity_check_80_func();
553 #endif
554
555 #if defined(BOOST_FLOAT128_C)
556    test_cstdfloat::sanity_check_128_func();
557
558    // Perform an extended check of boost::float128_t including
559    // a variety of functions from the C++ standard library.
560    test_cstdfloat::extend_check_128_func();
561 #endif // defined (BOOST_FLOAT128_C)
562 }