test_cpp_float_close_fraction.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. // Use, modification and distribution are subject to the
  2. // Boost Software License, Version 1.0. (See accompanying file
  3. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  4. // Copyright Paul A. Bristow 2013
  5. // Copyright Christopher Kormanyos 2013.
  6. // Copyright John Maddock 2013.
  7. #ifdef _MSC_VER
  8. # pragma warning (disable : 4512)
  9. # pragma warning (disable : 4996)
  10. #endif
  11. #define BOOST_TEST_MAIN
  12. #define BOOST_LIB_DIAGNOSTIC "on"// Show library file details.
  13. #include <boost/test/unit_test.hpp>
  14. #include <boost/test/tools/floating_point_comparison.hpp> // Extra test tool for FP comparison.
  15. #include <iostream>
  16. #include <limits>
  17. //[expression_template_1
  18. #include <boost/multiprecision/cpp_dec_float.hpp>
  19. /*`To define a 50 decimal digit type using `cpp_dec_float`,
  20. you must pass two template parameters to `boost::multiprecision::number`.
  21. It may be more legible to use a two-staged type definition such as this:
  22. ``
  23. typedef boost::multiprecision::cpp_dec_float<50> mp_backend;
  24. typedef boost::multiprecision::number<mp_backend, boost::multiprecision::et_off> cpp_dec_float_50_noet;
  25. ``
  26. Here, we first define `mp_backend` as `cpp_dec_float` with 50 digits.
  27. The second step passes this backend to `boost::multiprecision::number`
  28. with `boost::multiprecision::et_off`, an enumerated type.
  29. typedef boost::multiprecision::number<boost::multiprecision::cpp_dec_float<50>, boost::multiprecision::et_off>
  30. cpp_dec_float_50_noet;
  31. You can reduce typing with a `using` directive `using namespace boost::multiprecision;`
  32. if desired, as shown below.
  33. */
  34. using namespace boost::multiprecision;
  35. /*`Now `cpp_dec_float_50_noet` or `cpp_dec_float_50_et`
  36. can be used as a direct replacement for built-in types like `double` etc.
  37. */
  38. BOOST_AUTO_TEST_CASE(cpp_float_test_check_close_noet)
  39. { // No expression templates/
  40. typedef number<cpp_dec_float<50>, et_off> cpp_dec_float_50_noet;
  41. std::cout.precision(std::numeric_limits<cpp_dec_float_50_noet>::digits10); // All significant digits.
  42. std::cout << std::showpoint << std::endl; // Show trailing zeros.
  43. cpp_dec_float_50_noet a ("1.0");
  44. cpp_dec_float_50_noet b ("1.0");
  45. b += std::numeric_limits<cpp_dec_float_50_noet>::epsilon(); // Increment least significant decimal digit.
  46. cpp_dec_float_50_noet eps = std::numeric_limits<cpp_dec_float_50_noet>::epsilon();
  47. std::cout <<"a = " << a << ",\nb = " << b << ",\neps = " << eps << std::endl;
  48. BOOST_CHECK_CLOSE(a, b, eps * 100); // Expected to pass (because tolerance is as percent).
  49. BOOST_CHECK_CLOSE_FRACTION(a, b, eps); // Expected to pass (because tolerance is as fraction).
  50. } // BOOST_AUTO_TEST_CASE(cpp_float_test_check_close)
  51. BOOST_AUTO_TEST_CASE(cpp_float_test_check_close_et)
  52. { // Using expression templates.
  53. typedef number<cpp_dec_float<50>, et_on> cpp_dec_float_50_et;
  54. std::cout.precision(std::numeric_limits<cpp_dec_float_50_et>::digits10); // All significant digits.
  55. std::cout << std::showpoint << std::endl; // Show trailing zeros.
  56. cpp_dec_float_50_et a("1.0");
  57. cpp_dec_float_50_et b("1.0");
  58. b += std::numeric_limits<cpp_dec_float_50_et>::epsilon(); // Increment least significant decimal digit.
  59. cpp_dec_float_50_et eps = std::numeric_limits<cpp_dec_float_50_et>::epsilon();
  60. std::cout << "a = " << a << ",\nb = " << b << ",\neps = " << eps << std::endl;
  61. BOOST_CHECK_CLOSE(a, b, eps * 100); // Expected to pass (because tolerance is as percent).
  62. BOOST_CHECK_CLOSE_FRACTION(a, b, eps); // Expected to pass (because tolerance is as fraction).
  63. /*`Using `cpp_dec_float_50` with the default expression template use switched on,
  64. the compiler error message for `BOOST_CHECK_CLOSE_FRACTION(a, b, eps); would be:
  65. */
  66. // failure floating_point_comparison.hpp(59): error C2440: 'static_cast' :
  67. // cannot convert from 'int' to 'boost::multiprecision::detail::expression<tag,Arg1,Arg2,Arg3,Arg4>'
  68. //] [/expression_template_1]
  69. } // BOOST_AUTO_TEST_CASE(cpp_float_test_check_close)
  70. /*
  71. Output:
  72. Description: Autorun "J:\Cpp\big_number\Debug\test_cpp_float_close_fraction.exe"
  73. Running 1 test case...
  74. a = 1.0000000000000000000000000000000000000000000000000,
  75. b = 1.0000000000000000000000000000000000000000000000001,
  76. eps = 1.0000000000000000000000000000000000000000000000000e-49
  77. *** No errors detected
  78. */