test_zeta.hpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. // Copyright John Maddock 2006.
  2. // Copyright Paul A. Bristow 2007, 2009
  3. // Use, modification and distribution are subject to the
  4. // Boost Software License, Version 1.0. (See accompanying file
  5. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. #include <boost/math/concepts/real_concept.hpp>
  7. #include <boost/math/special_functions/math_fwd.hpp>
  8. #define BOOST_TEST_MAIN
  9. #include <boost/test/unit_test.hpp>
  10. #include <boost/test/tools/floating_point_comparison.hpp>
  11. #include <boost/math/tools/stats.hpp>
  12. #include <boost/math/tools/test.hpp>
  13. #include <boost/math/constants/constants.hpp>
  14. #include <boost/type_traits/is_floating_point.hpp>
  15. #include <boost/array.hpp>
  16. #include "functor.hpp"
  17. #include "handle_test_result.hpp"
  18. #include "table_type.hpp"
  19. #ifndef SC_
  20. #define SC_(x) static_cast<typename table_type<T>::type>(BOOST_JOIN(x, L))
  21. #endif
  22. template <class Real, class T>
  23. void do_test_zeta(const T& data, const char* type_name, const char* test_name)
  24. {
  25. #if !(defined(ERROR_REPORTING_MODE) && !defined(ZETA_FUNCTION_TO_TEST))
  26. //
  27. // test zeta(T) against data:
  28. //
  29. using namespace std;
  30. typedef Real value_type;
  31. std::cout << test_name << " with type " << type_name << std::endl;
  32. typedef value_type (*pg)(value_type);
  33. #ifdef ZETA_FUNCTION_TO_TEST
  34. pg funcp = ZETA_FUNCTION_TO_TEST;
  35. #elif defined(BOOST_MATH_NO_DEDUCED_FUNCTION_POINTERS)
  36. pg funcp = boost::math::zeta<value_type>;
  37. #else
  38. pg funcp = boost::math::zeta;
  39. #endif
  40. boost::math::tools::test_result<value_type> result;
  41. //
  42. // test zeta against data:
  43. //
  44. result = boost::math::tools::test_hetero<Real>(
  45. data,
  46. bind_func<Real>(funcp, 0),
  47. extract_result<Real>(1));
  48. handle_test_result(result, data[result.worst()], result.worst(), type_name, "zeta", test_name);
  49. std::cout << std::endl;
  50. #endif
  51. }
  52. template <class T>
  53. void test_zeta(T, const char* name)
  54. {
  55. //
  56. // The actual test data is rather verbose, so it's in a separate file
  57. //
  58. #include "zeta_data.ipp"
  59. do_test_zeta<T>(zeta_data, name, "Zeta: Random values greater than 1");
  60. #include "zeta_neg_data.ipp"
  61. do_test_zeta<T>(zeta_neg_data, name, "Zeta: Random values less than 1");
  62. #include "zeta_1_up_data.ipp"
  63. do_test_zeta<T>(zeta_1_up_data, name, "Zeta: Values close to and greater than 1");
  64. #include "zeta_1_below_data.ipp"
  65. do_test_zeta<T>(zeta_1_below_data, name, "Zeta: Values close to and less than 1");
  66. boost::array<boost::array<typename table_type<T>::type, 2>, 90> integer_data = { {
  67. {{ SC_(2.0), SC_(1.6449340668482264364724151666460252) }}, {{ SC_(3.0), SC_(1.2020569031595942853997381615114500) }}, {{ SC_(4.0), SC_(1.0823232337111381915160036965411679) }}, {{ SC_(5.0), SC_(1.0369277551433699263313654864570342) }}, {{ SC_(6.0), SC_(1.0173430619844491397145179297909205) }}, {{ SC_(7.0), SC_(1.0083492773819228268397975498497968) }}, {{ SC_(8.0), SC_(1.0040773561979443393786852385086525) }}, {{ SC_(9.0), SC_(1.0020083928260822144178527692324121) }}, {{ SC_(10.0), SC_(1.0009945751278180853371459589003190) }}, {{ SC_(11.0), SC_(1.0004941886041194645587022825264699) }}, {{ SC_(12.0), SC_(1.0002460865533080482986379980477397) }}, {{ SC_(13.0), SC_(1.0001227133475784891467518365263574) }}, {{ SC_(14.0), SC_(1.0000612481350587048292585451051353) }}, {{ SC_(15.0), SC_(1.0000305882363070204935517285106451) }}, {{ SC_(16.0), SC_(1.0000152822594086518717325714876367) }}, {{ SC_(17.0), SC_(1.0000076371976378997622736002935630) }}, {{ SC_(18.0), SC_(1.0000038172932649998398564616446219) }}, {{ SC_(19.0), SC_(1.0000019082127165539389256569577951) }}, {{ SC_(20.0), SC_(1.0000009539620338727961131520386834) }}, {{ SC_(21.0), SC_(1.0000004769329867878064631167196044) }}, {{ SC_(22.0), SC_(1.0000002384505027277329900036481868) }}, {{ SC_(23.0), SC_(1.0000001192199259653110730677887189) }}, {{ SC_(24.0), SC_(1.0000000596081890512594796124402079) }}, {{ SC_(25.0), SC_(1.0000000298035035146522801860637051) }}, {{ SC_(26.0), SC_(1.0000000149015548283650412346585066) }}, {{ SC_(27.0), SC_(1.0000000074507117898354294919810042) }}, {{ SC_(28.0), SC_(1.0000000037253340247884570548192040) }}, {{ SC_(29.0), SC_(1.0000000018626597235130490064039099) }}, {{ SC_(30.0), SC_(1.0000000009313274324196681828717647) }}, {{ SC_(31.0), SC_(1.0000000004656629065033784072989233) }}, {{ SC_(32.0), SC_(1.0000000002328311833676505492001456) }}, {{ SC_(33.0), SC_(1.0000000001164155017270051977592974) }}, {{ SC_(34.0), SC_(1.0000000000582077208790270088924369) }}, {{ SC_(35.0), SC_(1.0000000000291038504449709968692943) }}, {{ SC_(36.0), SC_(1.0000000000145519218910419842359296) }}, {{ SC_(37.0), SC_(1.0000000000072759598350574810145209) }}, {{ SC_(38.0), SC_(1.0000000000036379795473786511902372) }}, {{ SC_(39.0), SC_(1.0000000000018189896503070659475848) }}, {{ SC_(40.0), SC_(1.0000000000009094947840263889282533) }}, {{ SC_(41.0), SC_(1.0000000000004547473783042154026799) }}, {{ SC_(42.0), SC_(1.0000000000002273736845824652515227) }}, {{ SC_(43.0), SC_(1.0000000000001136868407680227849349) }}, {{ SC_(44.0), SC_(1.0000000000000568434198762758560928) }}, {{ SC_(45.0), SC_(1.0000000000000284217097688930185546) }}, {{ SC_(46.0), SC_(1.0000000000000142108548280316067698) }}, {{ SC_(47.0), SC_(1.0000000000000071054273952108527129) }}, {{ SC_(48.0), SC_(1.0000000000000035527136913371136733) }}, {{ SC_(49.0), SC_(1.0000000000000017763568435791203275) }}, {{ SC_(50.0), SC_(1.0000000000000008881784210930815903) }}, {{ SC_(51.0), SC_(1.0000000000000004440892103143813364) }}, {{ SC_(52.0), SC_(1.0000000000000002220446050798041984) }}, {{ SC_(53.0), SC_(1.0000000000000001110223025141066134) }}, {{ SC_(54.0), SC_(1.0000000000000000555111512484548124) }}, {{ SC_(55.0), SC_(1.0000000000000000277555756213612417) }}, {{ SC_(56.0), SC_(1.0000000000000000138777878097252328) }}, {{ SC_(57.0), SC_(1.0000000000000000069388939045441537) }}, {{ SC_(58.0), SC_(1.0000000000000000034694469521659226) }}, {{ SC_(59.0), SC_(1.0000000000000000017347234760475766) }}, {{ SC_(60.0), SC_(1.0000000000000000008673617380119934) }},
  68. {{ SC_(-61.0), SC_(-3.3066089876577576725680214670439210e34) }}, {{ SC_(-59.0), SC_(3.5666582095375556109684574608651829e32) }}, {{ SC_(-57.0), SC_(-4.1147288792557978697665486067619336e30) }}, {{ SC_(-55.0), SC_(5.0890659468662289689766332915911925e28) }}, {{ SC_(-53.0), SC_(-6.7645882379292820990945242301798478e26) }}, {{ SC_(-51.0), SC_(9.6899578874635940656497942894654088e24) }}, {{ SC_(-49.0), SC_(-1.5001733492153928733711440151515152e23) }}, {{ SC_(-47.0), SC_(2.5180471921451095697089023320225526e21) }}, {{ SC_(-45.0), SC_(-4.5979888343656503490437943262411348e19) }}, {{ SC_(-43.0), SC_(9.1677436031953307756992753623188406e17) }}, {{ SC_(-41.0), SC_(-2.0040310656516252738108421663238939e16) }}, {{ SC_(-39.0), SC_(4.8241448354850170371581670362158167e14) }}, {{ SC_(-37.0), SC_(-1.2850850499305083333333333333333333e13) }}, {{ SC_(-35.0), SC_(3.8087931125245368811553022079337869e11) }}, {{ SC_(-33.0), SC_(-1.2635724795916666666666666666666667e10) }}, {{ SC_(-31.0), SC_(4.7238486772162990196078431372549020e8) }}, {{ SC_(-29.0), SC_(-2.0052695796688078946143462272494531e7) }}, {{ SC_(-27.0), SC_(974936.82385057471264367816091954023) }}, {{ SC_(-25.0), SC_(-54827.583333333333333333333333333333) }}, {{ SC_(-23.0), SC_(3607.5105463980463980463980463980464) }}, {{ SC_(-21.0), SC_(-281.46014492753623188405797101449275) }}, {{ SC_(-19.0), SC_(26.456212121212121212121212121212121) }}, {{ SC_(-17.0), SC_(-3.0539543302701197438039543302701197) }}, {{ SC_(-15.0), SC_(0.44325980392156862745098039215686275) }}, {{ SC_(-13.0), SC_(-0.083333333333333333333333333333333333) }}, {{ SC_(-11.0), SC_(0.021092796092796092796092796092796093) }}, {{ SC_(-9.0), SC_(-0.0075757575757575757575757575757575758) }}, {{ SC_(-7.0), SC_(0.0041666666666666666666666666666666667) }}, {{ SC_(-5.0), SC_(-0.0039682539682539682539682539682539683) }}, {{ SC_(-3.0), SC_(0.0083333333333333333333333333333333333) }}, {{ SC_(-1.0), SC_(-0.083333333333333333333333333333333333) }}
  69. } };
  70. do_test_zeta<T>(integer_data, name, "Zeta: Integer arguments");
  71. }
  72. extern "C" double zetac(double);
  73. template <class T>
  74. void test_spots(T, const char* t)
  75. {
  76. std::cout << "Testing basic sanity checks for type " << t << std::endl;
  77. //
  78. // Basic sanity checks, tolerance is either 5 or 10 epsilon
  79. // expressed as a percentage:
  80. //
  81. BOOST_MATH_STD_USING
  82. T tolerance = boost::math::tools::epsilon<T>() * 100 *
  83. (boost::is_floating_point<T>::value ? 5 : 10);
  84. // An extra fudge factor for real_concept which has a less accurate tgamma:
  85. T tolerance_tgamma_extra = std::numeric_limits<T>::is_specialized ? 1 : 10;
  86. BOOST_CHECK_CLOSE(::boost::math::zeta(static_cast<T>(0.125)), static_cast<T>(-0.63277562349869525529352526763564627152686379131122L), tolerance);
  87. BOOST_CHECK_CLOSE(::boost::math::zeta(static_cast<T>(1023) / static_cast<T>(1024)), static_cast<T>(-1023.4228554489429786541032870895167448906103303056L), tolerance);
  88. BOOST_CHECK_CLOSE(::boost::math::zeta(static_cast<T>(1025) / static_cast<T>(1024)), static_cast<T>(1024.5772867695045940578681624248887776501597556226L), tolerance);
  89. BOOST_CHECK_CLOSE(::boost::math::zeta(static_cast<T>(0.5)), static_cast<T>(-1.46035450880958681288949915251529801246722933101258149054289L), tolerance);
  90. BOOST_CHECK_CLOSE(::boost::math::zeta(static_cast<T>(1.125)), static_cast<T>(8.5862412945105752999607544082693023591996301183069L), tolerance);
  91. BOOST_CHECK_CLOSE(::boost::math::zeta(static_cast<T>(2)), static_cast<T>(1.6449340668482264364724151666460251892189499012068L), tolerance);
  92. BOOST_CHECK_CLOSE(::boost::math::zeta(static_cast<T>(3.5)), static_cast<T>(1.1267338673170566464278124918549842722219969574036L), tolerance);
  93. BOOST_CHECK_CLOSE(::boost::math::zeta(static_cast<T>(4)), static_cast<T>(1.08232323371113819151600369654116790277475095191872690768298L), tolerance);
  94. BOOST_CHECK_CLOSE(::boost::math::zeta(4 + static_cast<T>(1) / 1024), static_cast<T>(1.08225596856391369799036835439238249195298434901488518878804L), tolerance);
  95. BOOST_CHECK_CLOSE(::boost::math::zeta(static_cast<T>(4.5)), static_cast<T>(1.05470751076145426402296728896028011727249383295625173068468L), tolerance);
  96. BOOST_CHECK_CLOSE(::boost::math::zeta(static_cast<T>(6.5)), static_cast<T>(1.01200589988852479610078491680478352908773213619144808841031L), tolerance);
  97. BOOST_CHECK_CLOSE(::boost::math::zeta(static_cast<T>(7.5)), static_cast<T>(1.00582672753652280770224164440459408011782510096320822989663L), tolerance);
  98. BOOST_CHECK_CLOSE(::boost::math::zeta(static_cast<T>(8.125)), static_cast<T>(1.0037305205308161603183307711439385250181080293472L), 2 * tolerance);
  99. BOOST_CHECK_CLOSE(::boost::math::zeta(static_cast<T>(16.125)), static_cast<T>(1.0000140128224754088474783648500235958510030511915L), tolerance);
  100. BOOST_CHECK_CLOSE(::boost::math::zeta(static_cast<T>(0)), static_cast<T>(-0.5L), tolerance);
  101. BOOST_CHECK_CLOSE(::boost::math::zeta(static_cast<T>(-0.125)), static_cast<T>(-0.39906966894504503550986928301421235400280637468895L), tolerance * tolerance_tgamma_extra);
  102. BOOST_CHECK_CLOSE(::boost::math::zeta(static_cast<T>(-1)), static_cast<T>(-0.083333333333333333333333333333333333333333333333333L), tolerance);
  103. BOOST_CHECK_CLOSE(::boost::math::zeta(static_cast<T>(-2)), static_cast<T>(0L), tolerance);
  104. BOOST_CHECK_CLOSE(::boost::math::zeta(static_cast<T>(-2.5)), static_cast<T>(0.0085169287778503305423585670283444869362759902200745L), tolerance * 3);
  105. BOOST_CHECK_CLOSE(::boost::math::zeta(static_cast<T>(-3)), static_cast<T>(0.0083333333333333333333333333333333333333333333333333L), tolerance);
  106. BOOST_CHECK_CLOSE(::boost::math::zeta(static_cast<T>(-4)), static_cast<T>(0), tolerance);
  107. BOOST_CHECK_CLOSE(::boost::math::zeta(static_cast<T>(-20)), static_cast<T>(0), tolerance * 100);
  108. BOOST_CHECK_CLOSE(::boost::math::zeta(static_cast<T>(-21)), static_cast<T>(-281.46014492753623188405797101449275362318840579710L), tolerance * 100);
  109. BOOST_CHECK_CLOSE(::boost::math::zeta(static_cast<T>(-30.125)), static_cast<T>(2.2762941726834511267740045451463455513839970804578e7L), tolerance * 100);
  110. // Very small values:
  111. BOOST_CHECK_CLOSE(::boost::math::zeta(ldexp(static_cast<T>(1), -20)), static_cast<T>(-0.500000876368989859479646132126454890645615288202492097957612L), tolerance);
  112. BOOST_CHECK_CLOSE(::boost::math::zeta(ldexp(static_cast<T>(1), -21)), static_cast<T>(-0.500000438184266833093492063649184012943132422189989164545507L), tolerance);
  113. BOOST_CHECK_CLOSE(::boost::math::zeta(ldexp(static_cast<T>(1), -22)), static_cast<T>(-0.500000219092076392425852854644256723571669269957526445270374L), tolerance);
  114. BOOST_CHECK_CLOSE(::boost::math::zeta(ldexp(static_cast<T>(1), -23)), static_cast<T>(-0.500000109546023940187789325464529558825433290921168958481804L), tolerance);
  115. BOOST_CHECK_CLOSE(::boost::math::zeta(ldexp(static_cast<T>(1), -24)), static_cast<T>(-0.500000054773008406088246161057525197302821575823476487961574L), tolerance);
  116. BOOST_CHECK_CLOSE(::boost::math::zeta(ldexp(static_cast<T>(1), -25)), static_cast<T>(-0.500000027386503312042790426817221131071450407798601059264341L), tolerance);
  117. BOOST_CHECK_CLOSE(::boost::math::zeta(ldexp(static_cast<T>(1), -26)), static_cast<T>(-0.500000013693251433271071983943082871935521396740331377486886L), tolerance);
  118. BOOST_CHECK_CLOSE(::boost::math::zeta(ldexp(static_cast<T>(1), -27)), static_cast<T>(-0.500000006846625660947956426350389518286874288247134329498289L), tolerance);
  119. BOOST_CHECK_CLOSE(::boost::math::zeta(ldexp(static_cast<T>(1), -28)), static_cast<T>(-0.500000003423312816552083476988056486473169377162409806781384L), tolerance);
  120. BOOST_CHECK_CLOSE(::boost::math::zeta(ldexp(static_cast<T>(1), -29)), static_cast<T>(-0.500000001711656404795568073849512135664960180586820144333542L), tolerance);
  121. BOOST_CHECK_CLOSE(::boost::math::zeta(ldexp(static_cast<T>(1), -30)), static_cast<T>(-0.500000000855828201527665623188910582717329375986726355164261L), tolerance);
  122. BOOST_CHECK_CLOSE(::boost::math::zeta(ldexp(static_cast<T>(1), -31)), static_cast<T>(-0.500000000427914100546303208463654361814800355929815322493143L), tolerance);
  123. BOOST_CHECK_CLOSE(::boost::math::zeta(ldexp(static_cast<T>(1), -32)), static_cast<T>(-0.500000000213957050218769203487022003676593508474107873788445L), tolerance);
  124. BOOST_CHECK_CLOSE(::boost::math::zeta(ldexp(static_cast<T>(1), -33)), static_cast<T>(-0.500000000106978525095789001562046589421133388262409441738089L), tolerance);
  125. BOOST_CHECK_CLOSE(::boost::math::zeta(ldexp(static_cast<T>(1), -34)), static_cast<T>(-0.500000000053489262544495600736249301842352101231724731340202L), tolerance);
  126. BOOST_CHECK_CLOSE(::boost::math::zeta(-ldexp(static_cast<T>(1), -20)), static_cast<T>(-0.499999123632834911086872289657767335473025908373776645822722L), tolerance * tolerance_tgamma_extra);
  127. BOOST_CHECK_CLOSE(::boost::math::zeta(-ldexp(static_cast<T>(1), -21)), static_cast<T>(-0.499999561816189359548137231641582253243376087534976981434190L), tolerance * tolerance_tgamma_extra);
  128. BOOST_CHECK_CLOSE(::boost::math::zeta(-ldexp(static_cast<T>(1), -22)), static_cast<T>(-0.499999780908037655734554449793729262345041281451929584703788L), tolerance * tolerance_tgamma_extra);
  129. BOOST_CHECK_CLOSE(::boost::math::zeta(-ldexp(static_cast<T>(1), -23)), static_cast<T>(-0.499999890454004571852312499433422838864632848598847415933664L), tolerance * tolerance_tgamma_extra);
  130. BOOST_CHECK_CLOSE(::boost::math::zeta(-ldexp(static_cast<T>(1), -24)), static_cast<T>(-0.499999945226998721921779295091241395945379526155584220813497L), tolerance * tolerance_tgamma_extra);
  131. BOOST_CHECK_CLOSE(::boost::math::zeta(-ldexp(static_cast<T>(1), -25)), static_cast<T>(-0.499999972613498469959715937215237923104705216198368099221577L), tolerance * tolerance_tgamma_extra);
  132. BOOST_CHECK_CLOSE(::boost::math::zeta(-ldexp(static_cast<T>(1), -26)), static_cast<T>(-0.499999986306749012229554607064736104475024094525587925697276L), tolerance * tolerance_tgamma_extra);
  133. BOOST_CHECK_CLOSE(::boost::math::zeta(-ldexp(static_cast<T>(1), -27)), static_cast<T>(-0.499999993153374450427200221401546739119918746163907954406855L), tolerance * tolerance_tgamma_extra);
  134. BOOST_CHECK_CLOSE(::boost::math::zeta(-ldexp(static_cast<T>(1), -28)), static_cast<T>(-0.499999996576687211291705684949926422460038672790251466963619L), tolerance * tolerance_tgamma_extra);
  135. BOOST_CHECK_CLOSE(::boost::math::zeta(-ldexp(static_cast<T>(1), -29)), static_cast<T>(-0.499999998288343602165379216634983519354686193860717726606017L), tolerance * tolerance_tgamma_extra);
  136. BOOST_CHECK_CLOSE(::boost::math::zeta(-ldexp(static_cast<T>(1), -30)), static_cast<T>(-0.499999999144171800212571199432213326524228740247618955829902L), tolerance * tolerance_tgamma_extra);
  137. BOOST_CHECK_CLOSE(::boost::math::zeta(-ldexp(static_cast<T>(1), -31)), static_cast<T>(-0.499999999572085899888755997191626615213504580792674808876724L), tolerance * tolerance_tgamma_extra);
  138. BOOST_CHECK_CLOSE(::boost::math::zeta(-ldexp(static_cast<T>(1), -32)), static_cast<T>(-0.499999999786042949889995597926798240562852438685508646794693L), tolerance);
  139. BOOST_CHECK_CLOSE(::boost::math::zeta(-ldexp(static_cast<T>(1), -33)), static_cast<T>(-0.499999999893021474931402198791408471637626205588681812641711L), tolerance);
  140. BOOST_CHECK_CLOSE(::boost::math::zeta(-ldexp(static_cast<T>(1), -34)), static_cast<T>(-0.499999999946510737462302199352114463422268928922372277519378L), tolerance);
  141. #ifdef BOOST_MSVC
  142. #pragma warning(push)
  143. #pragma warning(disable:4127 4756)
  144. #endif
  145. //
  146. // Very large negative values need special handling in our code, test them here, due to a bug report by Rocco Romeo:
  147. //
  148. BOOST_CHECK_EQUAL(::boost::math::zeta(static_cast<T>(-200)), static_cast<T>(0));
  149. if(std::numeric_limits<T>::max_exponent >= 1024)
  150. {
  151. BOOST_CHECK_CLOSE(::boost::math::zeta(static_cast<T>(-171)), static_cast<T>(1.28194898634822427378088228065956967928127061276520385040051e172L), tolerance * 200);
  152. BOOST_CHECK_CLOSE(::boost::math::zeta(static_cast<T>(-171.5)), static_cast<T>(4.73930233055054501360661283732419615206017226423071857829425e172L), tolerance * 1000);
  153. BOOST_CHECK_CLOSE(::boost::math::zeta(static_cast<T>(-172.5)), static_cast<T>(-1.30113885243175165293156588942160456456090687128236657847674e174L), tolerance * 100);
  154. BOOST_CHECK_CLOSE(::boost::math::zeta(static_cast<T>(-173)), static_cast<T>(-9.66241211085609184243169684777934860657838245104636064505158e174L), tolerance * 100);
  155. }
  156. if(std::numeric_limits<T>::has_infinity)
  157. {
  158. BOOST_CHECK_EQUAL(::boost::math::zeta(static_cast<T>(-10007)), std::numeric_limits<T>::infinity());
  159. BOOST_CHECK_EQUAL(::boost::math::zeta(static_cast<T>(-10009)), -std::numeric_limits<T>::infinity());
  160. }
  161. #ifdef BOOST_MSVC
  162. #pragma warning(pop)
  163. #endif
  164. }