test_cstdfloat.cpp 26 KB

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