test_numeric_limits.cpp 10 KB

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