test_float.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /* Boost test/test_float.cpp
  2. * test arithmetic operations on a range of intervals
  3. *
  4. * Copyright 2003 Guillaume Melquiond
  5. *
  6. * Distributed under the Boost Software License, Version 1.0.
  7. * (See accompanying file LICENSE_1_0.txt or
  8. * copy at http://www.boost.org/LICENSE_1_0.txt)
  9. */
  10. #include <boost/numeric/interval.hpp>
  11. #include <boost/test/test_tools.hpp>
  12. #include <boost/config.hpp>
  13. #include "bugs.hpp"
  14. /* All the following tests should be BOOST_CHECK; however, if a test fails,
  15. the probability is high that hundreds of other tests will fail, so it is
  16. replaced by BOOST_REQUIRE to avoid flooding the logs. */
  17. template<class T, class F>
  18. void test_unary() {
  19. typedef typename F::I I;
  20. for(I a(-10., -9.91); a.lower() <= 10.; a += 0.3) {
  21. if (!F::validate(a)) continue;
  22. I rI = F::f_I(a);
  23. T rT1 = F::f_T(a.lower()), rT2 = F::f_T(a.upper()),
  24. rT3 = F::f_T(median(a));
  25. BOOST_REQUIRE(in(rT1, rI));
  26. BOOST_REQUIRE(in(rT2, rI));
  27. BOOST_REQUIRE(in(rT3, rI));
  28. }
  29. }
  30. template<class T, class F>
  31. void test_binary() {
  32. typedef typename F::I I;
  33. for(I a(-10., -9.91); a.lower() <= 10.; a += 0.3) {
  34. for(I b(-10., -9.91); b.lower() <= 10.; b += 0.3) {
  35. if (!F::validate(a, b)) continue;
  36. T al = a.lower(), au = a.upper(), bl = b.lower(), bu = b.upper();
  37. I rII = F::f_II(a, b);
  38. I rIT1 = F::f_IT(a, bl), rIT2 = F::f_IT(a, bu);
  39. I rTI1 = F::f_TI(al, b), rTI2 = F::f_TI(au, b);
  40. I rTT1 = F::f_TT(al, bl), rTT2 = F::f_TT(al, bu);
  41. I rTT3 = F::f_TT(au, bl), rTT4 = F::f_TT(au, bu);
  42. BOOST_REQUIRE(subset(rTT1, rIT1));
  43. BOOST_REQUIRE(subset(rTT3, rIT1));
  44. BOOST_REQUIRE(subset(rTT2, rIT2));
  45. BOOST_REQUIRE(subset(rTT4, rIT2));
  46. BOOST_REQUIRE(subset(rTT1, rTI1));
  47. BOOST_REQUIRE(subset(rTT2, rTI1));
  48. BOOST_REQUIRE(subset(rTT3, rTI2));
  49. BOOST_REQUIRE(subset(rTT4, rTI2));
  50. BOOST_REQUIRE(subset(rIT1, rII));
  51. BOOST_REQUIRE(subset(rIT2, rII));
  52. BOOST_REQUIRE(subset(rTI1, rII));
  53. BOOST_REQUIRE(subset(rTI2, rII));
  54. }
  55. }
  56. }
  57. #define new_unary_bunch(name, op, val) \
  58. template<class T> \
  59. struct name { \
  60. typedef boost::numeric::interval<T> I; \
  61. static I f_I(const I& a) { return op(a); } \
  62. static T f_T(const T& a) { return op(a); } \
  63. static bool validate(const I& a) { return val; } \
  64. }
  65. //#ifndef BOOST_NO_STDC_NAMESPACE
  66. using std::abs;
  67. using std::sqrt;
  68. //#endif
  69. new_unary_bunch(bunch_pos, +, true);
  70. new_unary_bunch(bunch_neg, -, true);
  71. new_unary_bunch(bunch_sqrt, sqrt, a.lower() >= 0.);
  72. new_unary_bunch(bunch_abs, abs, true);
  73. template<class T>
  74. void test_all_unaries() {
  75. BOOST_TEST_CHECKPOINT("pos"); test_unary<T, bunch_pos<T> >();
  76. BOOST_TEST_CHECKPOINT("neg"); test_unary<T, bunch_neg<T> >();
  77. BOOST_TEST_CHECKPOINT("sqrt"); test_unary<T, bunch_sqrt<T> >();
  78. BOOST_TEST_CHECKPOINT("abs"); test_unary<T, bunch_abs<T> >();
  79. }
  80. #define new_binary_bunch(name, op, val) \
  81. template<class T> \
  82. struct bunch_##name { \
  83. typedef boost::numeric::interval<T> I; \
  84. static I f_II(const I& a, const I& b) { return a op b; } \
  85. static I f_IT(const I& a, const T& b) { return a op b; } \
  86. static I f_TI(const T& a, const I& b) { return a op b; } \
  87. static I f_TT(const T& a, const T& b) \
  88. { return boost::numeric::interval_lib::name<I>(a,b); } \
  89. static bool validate(const I& a, const I& b) { return val; } \
  90. }
  91. new_binary_bunch(add, +, true);
  92. new_binary_bunch(sub, -, true);
  93. new_binary_bunch(mul, *, true);
  94. new_binary_bunch(div, /, !zero_in(b));
  95. template<class T>
  96. void test_all_binaries() {
  97. BOOST_TEST_CHECKPOINT("add"); test_binary<T, bunch_add<T> >();
  98. BOOST_TEST_CHECKPOINT("sub"); test_binary<T, bunch_sub<T> >();
  99. BOOST_TEST_CHECKPOINT("mul"); test_binary<T, bunch_mul<T> >();
  100. BOOST_TEST_CHECKPOINT("div"); test_binary<T, bunch_div<T> >();
  101. }
  102. int test_main(int, char *[]) {
  103. BOOST_TEST_CHECKPOINT("float tests");
  104. test_all_unaries<float> ();
  105. test_all_binaries<float> ();
  106. BOOST_TEST_CHECKPOINT("double tests");
  107. test_all_unaries<double>();
  108. test_all_binaries<double>();
  109. //BOOST_TEST_CHECKPOINT("long double tests");
  110. //test_all_unaries<long double>();
  111. //test_all_binaries<long double>();
  112. # ifdef __BORLANDC__
  113. ::detail::ignore_warnings();
  114. # endif
  115. return 0;
  116. }