test_cpp_bin_float_round.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. // Copyright John Maddock 2016.
  2. // Use, modification and distribution are subject to the
  3. // Boost Software License, Version 1.0.
  4. // (See accompanying file LICENSE_1_0.txt
  5. // or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // This file takes way too long to run to be part of the main regression test suite,
  8. // but is useful in probing for errors in cpp_bin_float's rounding code.
  9. // It cycles through every single value of type float, and rounds those numbers
  10. // plus some closely related ones and compares the results to those produced by MPFR.
  11. //
  12. #ifdef _MSC_VER
  13. #define _SCL_SECURE_NO_WARNINGS
  14. #endif
  15. #include <boost/multiprecision/cpp_bin_float.hpp>
  16. #include <boost/multiprecision/mpfr.hpp>
  17. #include <boost/math/special_functions/next.hpp>
  18. #include "test.hpp"
  19. using namespace boost::multiprecision;
  20. typedef number<mpfr_float_backend<35> > good_type;
  21. typedef number<cpp_bin_float<std::numeric_limits<good_type>::digits, digit_base_2>, et_off> test_type;
  22. int main()
  23. {
  24. float f = (std::numeric_limits<float>::max)();
  25. do
  26. {
  27. float fr1, fr2;
  28. good_type gf(f), gf2(f);
  29. test_type tf(f), tf2(f);
  30. fr1 = gf.convert_to<float>();
  31. fr2 = tf.convert_to<float>();
  32. BOOST_CHECK_EQUAL(fr1, fr2);
  33. // next represenation:
  34. gf = boost::math::float_next(gf2);
  35. tf = boost::math::float_next(tf2);
  36. BOOST_CHECK_NE(gf, gf2);
  37. BOOST_CHECK_NE(tf, tf2);
  38. fr1 = gf.convert_to<float>();
  39. fr2 = tf.convert_to<float>();
  40. BOOST_CHECK_EQUAL(fr1, fr2);
  41. // previous representation:
  42. gf = boost::math::float_prior(gf2);
  43. tf = boost::math::float_prior(tf2);
  44. BOOST_CHECK_NE(gf, gf2);
  45. BOOST_CHECK_NE(tf, tf2);
  46. fr1 = gf.convert_to<float>();
  47. fr2 = tf.convert_to<float>();
  48. BOOST_CHECK_EQUAL(fr1, fr2);
  49. // Create ands test ties:
  50. int e;
  51. std::frexp(f, &e);
  52. float extra = std::ldexp(1.0f, e - std::numeric_limits<float>::digits - 1);
  53. gf = gf2 += extra;
  54. tf = tf2 += extra;
  55. fr1 = gf.convert_to<float>();
  56. fr2 = tf.convert_to<float>();
  57. BOOST_CHECK_EQUAL(fr1, fr2);
  58. // next represenation:
  59. gf = boost::math::float_next(gf2);
  60. tf = boost::math::float_next(tf2);
  61. BOOST_CHECK_NE(gf, gf2);
  62. BOOST_CHECK_NE(tf, tf2);
  63. fr1 = gf.convert_to<float>();
  64. fr2 = tf.convert_to<float>();
  65. BOOST_CHECK_EQUAL(fr1, fr2);
  66. // previous representation:
  67. gf = boost::math::float_prior(gf2);
  68. tf = boost::math::float_prior(tf2);
  69. BOOST_CHECK_NE(gf, gf2);
  70. BOOST_CHECK_NE(tf, tf2);
  71. fr1 = gf.convert_to<float>();
  72. fr2 = tf.convert_to<float>();
  73. BOOST_CHECK_EQUAL(fr1, fr2);
  74. f = boost::math::float_prior(f);
  75. } while (f);
  76. return boost::report_errors();
  77. }