]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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_TEST_CHECKPOINT("pos"); test_unary<T, bunch_pos<T> >(); | |
84 | BOOST_TEST_CHECKPOINT("neg"); test_unary<T, bunch_neg<T> >(); | |
85 | BOOST_TEST_CHECKPOINT("sqrt"); test_unary<T, bunch_sqrt<T> >(); | |
86 | BOOST_TEST_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, /, !zero_in(b)); | |
105 | ||
106 | template<class T> | |
107 | void test_all_binaries() { | |
108 | BOOST_TEST_CHECKPOINT("add"); test_binary<T, bunch_add<T> >(); | |
109 | BOOST_TEST_CHECKPOINT("sub"); test_binary<T, bunch_sub<T> >(); | |
110 | BOOST_TEST_CHECKPOINT("mul"); test_binary<T, bunch_mul<T> >(); | |
111 | BOOST_TEST_CHECKPOINT("div"); test_binary<T, bunch_div<T> >(); | |
112 | } | |
113 | ||
114 | int test_main(int, char *[]) { | |
115 | BOOST_TEST_CHECKPOINT("float tests"); | |
116 | test_all_unaries<float> (); | |
117 | test_all_binaries<float> (); | |
118 | BOOST_TEST_CHECKPOINT("double tests"); | |
119 | test_all_unaries<double>(); | |
120 | test_all_binaries<double>(); | |
121 | //BOOST_TEST_CHECKPOINT("long double tests"); | |
122 | //test_all_unaries<long double>(); | |
123 | //test_all_binaries<long double>(); | |
20effc67 | 124 | # ifdef BOOST_BORLANDC |
7c673cae FG |
125 | ::detail::ignore_warnings(); |
126 | # endif | |
127 | return 0; | |
128 | } |