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