test_sign.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. #define BOOST_TEST_MAIN// Copyright John Maddock 2008
  2. // (C) Copyright Paul A. Bristow 2011 (added tests for changesign)
  3. // Use, modification and distribution are subject to the
  4. // Boost Software License, Version 1.0.
  5. // (See accompanying file LICENSE_1_0.txt
  6. // or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. #include <boost/math/concepts/real_concept.hpp> // for real_concept
  8. #include <boost/math/special_functions/sign.hpp>
  9. #define BOOST_TEST_MAIN
  10. #include <boost/test/unit_test.hpp> // Boost.Test
  11. #include <boost/test/results_collector.hpp>
  12. #include <boost/test/unit_test.hpp>
  13. #include <boost/test/tools/floating_point_comparison.hpp>
  14. #include <iostream>
  15. using std::cout;
  16. using std::endl;
  17. using std::setprecision;
  18. template <class RealType>
  19. void test_spots(RealType /*T*/, const char* /*type_name*/)
  20. {
  21. // Basic sanity checks.
  22. RealType a = 0;
  23. RealType b = 1;
  24. RealType c = -1;
  25. BOOST_CHECK_EQUAL((boost::math::signbit)(a), 0);
  26. BOOST_CHECK_EQUAL((boost::math::sign)(a), 0);
  27. BOOST_CHECK_EQUAL((boost::math::changesign)(b), RealType(-1));
  28. BOOST_CHECK_EQUAL((boost::math::changesign)(c), RealType(+1));
  29. BOOST_CHECK_EQUAL((boost::math::changesign)(a), RealType(0));
  30. // Compare to formula for changsign(x) = copysign(x, signbit(x) ? 1.0 : -1.0)
  31. BOOST_CHECK_EQUAL((boost::math::changesign)(b),
  32. (boost::math::copysign)(b, (boost::math::signbit)(b) ? RealType(1.) : RealType(-1.) ));
  33. BOOST_CHECK_EQUAL((boost::math::copysign)(b, a), RealType(1));
  34. BOOST_CHECK_EQUAL((boost::math::copysign)(c, a), RealType(1));
  35. a = 1;
  36. BOOST_CHECK_EQUAL((boost::math::signbit)(a), 0);
  37. BOOST_CHECK_EQUAL((boost::math::sign)(a), 1);
  38. BOOST_CHECK_EQUAL((boost::math::copysign)(b, a), RealType(1));
  39. BOOST_CHECK_EQUAL((boost::math::copysign)(c, a), RealType(1));
  40. a = -1;
  41. BOOST_CHECK((boost::math::signbit)(a) != 0);
  42. BOOST_CHECK_EQUAL((boost::math::sign)(a), -1);
  43. BOOST_CHECK_EQUAL((boost::math::copysign)(b, a), RealType(-1));
  44. BOOST_CHECK_EQUAL((boost::math::copysign)(c, a), RealType(-1));
  45. a = boost::math::tools::max_value<RealType>();
  46. BOOST_CHECK_EQUAL((boost::math::signbit)(a), 0);
  47. BOOST_CHECK_EQUAL((boost::math::sign)(a), 1);
  48. BOOST_CHECK_EQUAL((boost::math::copysign)(b, a), RealType(1));
  49. BOOST_CHECK_EQUAL((boost::math::copysign)(c, a), RealType(1));
  50. a = -boost::math::tools::max_value<RealType>();
  51. BOOST_CHECK((boost::math::signbit)(a) != 0);
  52. BOOST_CHECK_EQUAL((boost::math::sign)(a), -1);
  53. BOOST_CHECK_EQUAL((boost::math::copysign)(b, a), RealType(-1));
  54. BOOST_CHECK_EQUAL((boost::math::copysign)(c, a), RealType(-1));
  55. if(std::numeric_limits<RealType>::has_infinity)
  56. {
  57. a = std::numeric_limits<RealType>::infinity();
  58. BOOST_CHECK_EQUAL((boost::math::signbit)(a), 0);
  59. BOOST_CHECK_EQUAL((boost::math::sign)(a), 1);
  60. BOOST_CHECK_EQUAL((boost::math::copysign)(b, a), RealType(1));
  61. BOOST_CHECK_EQUAL((boost::math::copysign)(c, a), RealType(1));
  62. BOOST_CHECK_EQUAL((boost::math::changesign)(a), -a);
  63. a = -std::numeric_limits<RealType>::infinity();
  64. BOOST_CHECK((boost::math::signbit)(a) != 0);
  65. BOOST_CHECK_EQUAL((boost::math::sign)(a), -1);
  66. BOOST_CHECK_EQUAL((boost::math::copysign)(b, a), RealType(-1));
  67. BOOST_CHECK_EQUAL((boost::math::copysign)(c, a), RealType(-1));
  68. BOOST_CHECK_EQUAL((boost::math::changesign)(a), -a);
  69. }
  70. #if !defined(__SUNPRO_CC) && !defined(BOOST_INTEL)
  71. if(std::numeric_limits<RealType>::has_quiet_NaN)
  72. {
  73. a = std::numeric_limits<RealType>::quiet_NaN();
  74. BOOST_CHECK_EQUAL((boost::math::signbit)(a), 0);
  75. BOOST_CHECK_EQUAL((boost::math::sign)(a), 1);
  76. BOOST_CHECK_EQUAL((boost::math::copysign)(b, a), RealType(1));
  77. BOOST_CHECK_EQUAL((boost::math::copysign)(c, a), RealType(1));
  78. // BOOST_CHECK_EQUAL((boost::math::changesign)(a), -a); // NaN comparison fails always!
  79. BOOST_CHECK((boost::math::signbit)((boost::math::changesign)(a)) != 0);
  80. a = -std::numeric_limits<RealType>::quiet_NaN();
  81. BOOST_CHECK((boost::math::signbit)(a) != 0);
  82. BOOST_CHECK_EQUAL((boost::math::sign)(a), -1);
  83. BOOST_CHECK_EQUAL((boost::math::copysign)(b, a), RealType(-1));
  84. BOOST_CHECK_EQUAL((boost::math::copysign)(c, a), RealType(-1));
  85. //BOOST_CHECK_EQUAL((boost::math::changesign)(a), -a); // NaN comparison fails always!
  86. BOOST_CHECK_EQUAL((boost::math::signbit)((boost::math::changesign)(a)), 0);
  87. }
  88. #endif
  89. //
  90. // Try some extreme values:
  91. //
  92. a = boost::math::tools::min_value<RealType>();
  93. b = -a;
  94. c = -1;
  95. BOOST_CHECK((boost::math::signbit)(a) == 0);
  96. BOOST_CHECK_EQUAL((boost::math::sign)(a), 1);
  97. BOOST_CHECK_EQUAL((boost::math::copysign)(c, a), RealType(1));
  98. BOOST_CHECK((boost::math::signbit)(b) != 0);
  99. BOOST_CHECK_EQUAL((boost::math::sign)(b), -1);
  100. c = 1;
  101. BOOST_CHECK_EQUAL((boost::math::copysign)(c, b), RealType(-1));
  102. //
  103. // try denormalised values:
  104. //
  105. a /= 4;
  106. if(a != 0)
  107. {
  108. b = -a;
  109. c = -1;
  110. BOOST_CHECK((boost::math::signbit)(a) == 0);
  111. BOOST_CHECK_EQUAL((boost::math::sign)(a), 1);
  112. BOOST_CHECK_EQUAL((boost::math::copysign)(c, a), RealType(1));
  113. BOOST_CHECK((boost::math::signbit)(b) != 0);
  114. BOOST_CHECK_EQUAL((boost::math::sign)(b), -1);
  115. c = 1;
  116. BOOST_CHECK_EQUAL((boost::math::copysign)(c, b), RealType(-1));
  117. }
  118. a = boost::math::tools::max_value<RealType>() / 2;
  119. b = -a;
  120. c = -1;
  121. BOOST_CHECK((boost::math::signbit)(a) == 0);
  122. BOOST_CHECK_EQUAL((boost::math::sign)(a), 1);
  123. BOOST_CHECK_EQUAL((boost::math::copysign)(c, a), RealType(1));
  124. BOOST_CHECK((boost::math::signbit)(b) != 0);
  125. BOOST_CHECK_EQUAL((boost::math::sign)(b), -1);
  126. c = 1;
  127. BOOST_CHECK_EQUAL((boost::math::copysign)(c, b), RealType(-1));
  128. }
  129. BOOST_AUTO_TEST_CASE( test_main )
  130. {
  131. // Basic sanity-check spot values.
  132. // (Parameter value, arbitrarily zero, only communicates the floating point type).
  133. test_spots(0.0F, "float"); // Test float. OK at decdigits = 0 tolerance = 0.0001 %
  134. test_spots(0.0, "double"); // Test double. OK at decdigits 7, tolerance = 1e07 %
  135. // long double support for the sign functions is considered "core" so we always test it
  136. // even when long double support is turned off via BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
  137. test_spots(0.0L, "long double"); // Test long double.
  138. #ifndef BOOST_MATH_NO_REAL_CONCEPT_TESTS
  139. test_spots(boost::math::concepts::real_concept(0), "real_concept"); // Test real_concept.
  140. #endif
  141. } // BOOST_AUTO_TEST_CASE( test_main )