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