math_sqrt.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Unit Test
  3. // Copyright (c) 2014, Oracle and/or its affiliates.
  4. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
  5. // Licensed under the Boost Software License version 1.0.
  6. // http://www.boost.org/users/license.html
  7. #ifndef BOOST_TEST_MODULE
  8. #define BOOST_TEST_MODULE test_math_sqrt
  9. #endif
  10. #include <cmath>
  11. #include <iostream>
  12. #include <boost/test/included/unit_test.hpp>
  13. #include <boost/config.hpp>
  14. #include <boost/type_traits/is_fundamental.hpp>
  15. #include "number_types.hpp"
  16. // important: the include above must precede the include below,
  17. // otherwise the test will fail for the custom number type:
  18. // custom_with_global_sqrt
  19. #include <boost/geometry/util/math.hpp>
  20. #include <boost/geometry/algorithms/not_implemented.hpp>
  21. #ifdef HAVE_TTMATH
  22. # include <boost/geometry/extensions/contrib/ttmath_stub.hpp>
  23. #endif
  24. namespace bg = boost::geometry;
  25. // call BOOST_CHECK
  26. template <typename Argument, bool IsFundamental /* true */>
  27. struct check
  28. {
  29. template <typename Result>
  30. static inline void apply(Argument const& arg, Result const& result)
  31. {
  32. BOOST_CHECK_CLOSE(static_cast<double>(bg::math::sqrt(arg)),
  33. static_cast<double>(result),
  34. 0.00001);
  35. }
  36. };
  37. template <typename Argument>
  38. struct check<Argument, false>
  39. {
  40. template <typename Result>
  41. static inline void apply(Argument const& arg, Result const& result)
  42. {
  43. Result const tol(0.00001);
  44. BOOST_CHECK( bg::math::abs(bg::math::sqrt(arg) - result) < tol );
  45. }
  46. };
  47. // test sqrt return type and value
  48. template
  49. <
  50. typename Argument,
  51. typename ExpectedResult,
  52. typename Result = typename bg::math::detail::square_root
  53. <
  54. Argument
  55. >::return_type,
  56. bool IsFundamental = boost::is_fundamental<Argument>::value
  57. >
  58. struct check_sqrt
  59. : bg::not_implemented<Argument, Result, ExpectedResult>
  60. {};
  61. template <typename Argument, typename Result, bool IsFundamental>
  62. struct check_sqrt<Argument, Result, Result, IsFundamental>
  63. {
  64. static inline void apply(Argument const& arg, Result const& result)
  65. {
  66. #ifdef BOOST_GEOMETRY_TEST_DEBUG
  67. std::cout << "testing: " << typeid(Result).name()
  68. << " sqrt(" << typeid(Argument).name()
  69. << ")" << std::endl;
  70. #endif
  71. check<Argument, IsFundamental>::apply(arg, result);
  72. }
  73. };
  74. // test cases
  75. BOOST_AUTO_TEST_CASE( test_math_sqrt_fundamental )
  76. {
  77. static const double sqrt2 = std::sqrt(2.0);
  78. static const long double sqrt2L = std::sqrt(2.0L);
  79. static const float sqrt2F = std::sqrt(2.0F);
  80. check_sqrt<float, float>::apply(2.0F, sqrt2F);
  81. check_sqrt<double, double>::apply(2.0, sqrt2);
  82. check_sqrt<long double, long double>::apply(2.0L, sqrt2L);
  83. check_sqrt<char, double>::apply(2, sqrt2);
  84. check_sqrt<signed char, double>::apply(2, sqrt2);
  85. check_sqrt<short, double>::apply(2, sqrt2);
  86. check_sqrt<int, double>::apply(2, sqrt2);
  87. check_sqrt<long, double>::apply(2L, sqrt2);
  88. #if !defined(BOOST_NO_LONG_LONG)
  89. check_sqrt<long long, double>::apply(2LL, sqrt2);
  90. #endif
  91. #ifdef BOOST_HAS_LONG_LONG
  92. check_sqrt
  93. <
  94. boost::long_long_type, double
  95. >::apply(boost::long_long_type(2), sqrt2);
  96. #endif
  97. }
  98. BOOST_AUTO_TEST_CASE( test_math_sqrt_custom )
  99. {
  100. typedef number_types::custom<double> custom1;
  101. typedef custom_global<double> custom2;
  102. typedef number_types::custom_with_global_sqrt<double> custom3;
  103. static const double sqrt2 = std::sqrt(2.0);
  104. check_sqrt<custom1, custom1>::apply(custom1(2.0), custom1(sqrt2));
  105. check_sqrt<custom2, custom2>::apply(custom2(2.0), custom2(sqrt2));
  106. check_sqrt<custom3, custom3>::apply(custom3(2.0), custom3(sqrt2));
  107. #ifdef HAVE_TTMATH
  108. typedef ttmath_big custom4;
  109. typedef ttmath::Big<1, 4> custom5;
  110. check_sqrt<custom4, custom4>::apply(custom4(2.0), custom4(sqrt2));
  111. check_sqrt<custom5, custom5>::apply(custom5(2.0), custom5(sqrt2));
  112. #endif
  113. }