test_legacy_nonfinite.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. // Copyright (c) 2006 Johan Rade
  2. // Copyright (c) 2011 Paul A. Bristow comments
  3. // Distributed under the 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. \file
  8. \brief Legacy (non-C99) tests of the nonfinite num facets.
  9. \detail legacy_test outputs using nonfinite_num_put facet
  10. with legacy flag, and reads back in using nonfinite_num_ facet,
  11. and checks loopback OK.
  12. Also checks that output of infinity, -infinity and NaN are as expected,
  13. including the 'legacy' "1.#IND", "1.#QNAN", "1.#SNAN" representations
  14. (was used by MSVC but now all represented on output by "1.#QNAN")
  15. and qnan snan nanq nans (used by other systems)
  16. excluding C99 specification "nan -nan nan -nan" and "inf -inf".
  17. */
  18. #ifdef _MSC_VER
  19. # pragma warning(disable : 4702)
  20. #endif
  21. #include <iomanip>
  22. #include <locale>
  23. #include <sstream>
  24. #define BOOST_TEST_MAIN
  25. #include <boost/test/unit_test.hpp>
  26. //#include "almost_equal.hpp"
  27. //#include "S_.hpp"
  28. #include <boost/math/special_functions/nonfinite_num_facets.hpp>
  29. namespace {
  30. // The anonymous namespace resolves ambiguities on platforms
  31. // with fpclassify etc functions declared at global scope.
  32. using namespace boost::math;
  33. using boost::math::signbit;
  34. using boost::math::changesign;
  35. using boost::math::isnan;
  36. //------------------------------------------------------------------------------
  37. void legacy_test_inf();
  38. void legacy_test_nan();
  39. BOOST_AUTO_TEST_CASE(legacy_test)
  40. {
  41. legacy_test_inf();
  42. legacy_test_nan();
  43. }
  44. //------------------------------------------------------------------------------
  45. template<class CharType, class ValType> void legacy_test_inf_impl();
  46. void legacy_test_inf()
  47. {
  48. legacy_test_inf_impl<char, float>();
  49. legacy_test_inf_impl<char, double>();
  50. legacy_test_inf_impl<char, long double>();
  51. legacy_test_inf_impl<wchar_t, float>();
  52. legacy_test_inf_impl<wchar_t, double>();
  53. legacy_test_inf_impl<wchar_t, long double>();
  54. }
  55. template<class CharType, class ValType> void legacy_test_inf_impl()
  56. {
  57. std::locale old_locale;
  58. std::locale new_locale(old_locale, new nonfinite_num_get<CharType>(legacy));
  59. std::basic_stringstream<CharType> ss;
  60. ss.imbue(new_locale);
  61. ValType a1 = std::numeric_limits<ValType>::infinity();
  62. ValType a2 = -std::numeric_limits<ValType>::infinity();
  63. ss << a1 << ' ' << a2;
  64. ss << " 1.#INF";
  65. ValType b1, b2, b3;
  66. ss >> b1 >> b2 >> b3;
  67. BOOST_CHECK(b1 == a1);
  68. BOOST_CHECK(b2 == a2);
  69. BOOST_CHECK(b3 == std::numeric_limits<ValType>::infinity());
  70. BOOST_CHECK(ss.rdstate() == std::ios_base::eofbit);
  71. }
  72. //------------------------------------------------------------------------------
  73. template<class CharType, class ValType> void legacy_test_nan_impl();
  74. void legacy_test_nan()
  75. {
  76. legacy_test_nan_impl<char, float>();
  77. legacy_test_nan_impl<char, double>();
  78. legacy_test_nan_impl<char, long double>();
  79. legacy_test_nan_impl<wchar_t, float>();
  80. legacy_test_nan_impl<wchar_t, double>();
  81. legacy_test_nan_impl<wchar_t, long double>();
  82. }
  83. template<class CharType, class ValType> void legacy_test_nan_impl()
  84. {
  85. std::locale old_locale;
  86. std::locale new_locale(old_locale, new nonfinite_num_get<CharType>(legacy));
  87. std::basic_stringstream<CharType> ss;
  88. ss.imbue(new_locale);
  89. ValType a1 = std::numeric_limits<ValType>::quiet_NaN();
  90. ValType a2 = -std::numeric_limits<ValType>::quiet_NaN();
  91. ValType a3 = std::numeric_limits<ValType>::signaling_NaN();
  92. ValType a4 = -std::numeric_limits<ValType>::signaling_NaN();
  93. ss << a1 << ' ' << a2 << ' ' << a3 << ' ' << a4;
  94. ss << " qnan snan nanq nans 1.#IND 1.#QNAN 1.#SNAN";
  95. ValType b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11;
  96. ss >> b1 >> b2 >> b3 >> b4 >> b5 >> b6 >> b7 >> b8 >> b9 >> b10 >> b11;
  97. // std::cout << b11 << std::endl; // Confirms that legacy
  98. // IND, SNAN and QNAN are considered the same,
  99. // and both output the legacy string "1.#QNAN".
  100. BOOST_CHECK((isnan)(b1));
  101. BOOST_CHECK((isnan)(b2));
  102. BOOST_CHECK((isnan)(b3));
  103. BOOST_CHECK((isnan)(b4));
  104. BOOST_CHECK((isnan)(b5));
  105. BOOST_CHECK((isnan)(b6));
  106. BOOST_CHECK((isnan)(b7));
  107. BOOST_CHECK((isnan)(b8));
  108. BOOST_CHECK((isnan)(b9));
  109. BOOST_CHECK((isnan)(b10));
  110. BOOST_CHECK((isnan)(b11)); // Johan V3 1.#SNAN failed on MSVC 10.
  111. // Change in nonfinite_num_facet.hpp Paul A. Bristow 11 Apr 11 makes work OK.
  112. /*
  113. // These tests fail on platforms, such as gcc,
  114. // that use the same representation of +nan and -nan.
  115. BOOST_CHECK(!(signbit)(b1));
  116. BOOST_CHECK((signbit)(b2));
  117. BOOST_CHECK(!(signbit)(b3));
  118. BOOST_CHECK((signbit)(b4));
  119. */
  120. BOOST_CHECK(!(signbit)(b5));
  121. BOOST_CHECK(!(signbit)(b6));
  122. BOOST_CHECK(!(signbit)(b7));
  123. BOOST_CHECK(!(signbit)(b8));
  124. BOOST_CHECK(!(signbit)(b9));
  125. BOOST_CHECK(!(signbit)(b10));
  126. BOOST_CHECK(!(signbit)(b11)); // Johan V3 1.#SNAN failed MSVC 10.
  127. BOOST_CHECK(ss.rdstate() == std::ios_base::eofbit); // Fails if SNAN test fails.
  128. }
  129. //------------------------------------------------------------------------------
  130. } // anonymous namespace
  131. /*
  132. Output:
  133. legacy_test.vcxproj -> J:\Cpp\fp_facet\fp_facet\Debug\legacy_test.exe
  134. Running 1 test case...
  135. 1.#QNAN
  136. 1.#QNAN
  137. 1.#QNAN
  138. 1.#QNAN
  139. 1.#QNAN
  140. 1.#QNAN
  141. *** No errors detected
  142. */