]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Copyright John Maddock 2013. |
2 | ||
3 | // Use, modification and distribution are subject to the | |
4 | // Boost Software License, Version 1.0. | |
5 | // (See accompanying file LICENSE_1_0.txt | |
6 | // or copy at http://www.boost.org/LICENSE_1_0.txt) | |
7 | ||
8 | #ifdef _MSC_VER | |
92f5a8d4 | 9 | #define _SCL_SECURE_NO_WARNINGS |
7c673cae FG |
10 | #endif |
11 | ||
12 | #include <boost/multiprecision/cpp_bin_float.hpp> | |
13 | #ifdef TEST_MPFR | |
14 | #include <boost/multiprecision/mpfr.hpp> | |
15 | #endif | |
16 | #include <boost/random/mersenne_twister.hpp> | |
17 | #include <boost/random/uniform_int.hpp> | |
18 | #include "libs/multiprecision/test/test.hpp" | |
19 | #include <iostream> | |
20 | #include <iomanip> | |
21 | ||
22 | template <class T> | |
23 | T generate_random() | |
24 | { | |
92f5a8d4 | 25 | typedef int e_type; |
7c673cae | 26 | static boost::random::mt19937 gen; |
92f5a8d4 TL |
27 | T val = gen(); |
28 | T prev_val = -1; | |
29 | while (val != prev_val) | |
7c673cae FG |
30 | { |
31 | val *= (gen.max)(); | |
32 | prev_val = val; | |
33 | val += gen(); | |
34 | } | |
35 | e_type e; | |
36 | val = frexp(val, &e); | |
37 | ||
38 | static boost::random::uniform_int_distribution<e_type> ui(-20, 20); | |
39 | return ldexp(val, ui(gen)); | |
40 | } | |
41 | ||
7c673cae FG |
42 | using namespace boost::multiprecision; |
43 | #ifdef TEST_MPFR | |
44 | typedef number<mpfr_float_backend<35> > good_type; | |
45 | #else | |
46 | typedef double good_type; | |
47 | #endif | |
48 | typedef number<cpp_bin_float<std::numeric_limits<good_type>::digits, digit_base_2>, et_off> test_type; | |
49 | ||
50 | void test_special_cases() | |
51 | { | |
92f5a8d4 TL |
52 | test_type max_val = (std::numeric_limits<test_type>::max)(); |
53 | test_type min_val = (std::numeric_limits<test_type>::min)(); | |
54 | test_type eps = std::numeric_limits<test_type>::epsilon(); | |
55 | test_type inf_val = (std::numeric_limits<test_type>::infinity)(); | |
56 | test_type nan_val = (std::numeric_limits<test_type>::quiet_NaN)(); | |
57 | test_type half = 0.5; | |
7c673cae | 58 | test_type one_point_5 = 1.5; |
92f5a8d4 | 59 | |
7c673cae FG |
60 | BOOST_CHECK((boost::math::isnormal)(max_val)); |
61 | BOOST_CHECK((boost::math::isnormal)(-max_val)); | |
62 | BOOST_CHECK((boost::math::isnormal)(min_val)); | |
63 | BOOST_CHECK((boost::math::isnormal)(-min_val)); | |
64 | BOOST_CHECK((boost::math::isinf)(inf_val)); | |
65 | BOOST_CHECK((boost::math::isinf)(-inf_val)); | |
66 | BOOST_CHECK((boost::math::isnan)(nan_val)); | |
67 | BOOST_CHECK((boost::math::isnan)(-nan_val)); | |
68 | ||
92f5a8d4 | 69 | if (std::numeric_limits<test_type>::has_denorm) |
7c673cae FG |
70 | min_val = std::numeric_limits<test_type>::denorm_min(); |
71 | ||
72 | // Adding epsilon will increment 1.0: | |
73 | BOOST_CHECK(test_type(1) + eps != test_type(1)); | |
74 | BOOST_CHECK(test_type(1) + eps / 2 == test_type(1)); | |
75 | // But it's not the smallest value that will do that: | |
76 | test_type small = 1 + eps; | |
92f5a8d4 | 77 | small = ldexp(small, -std::numeric_limits<test_type>::digits); |
7c673cae | 78 | BOOST_CHECK(test_type(1) + small != test_type(1)); |
92f5a8d4 | 79 | // And if we increment 1.0 first, then an even smaller |
7c673cae FG |
80 | // addition will round up: |
81 | test_type one_next = test_type(1) + eps; | |
82 | BOOST_CHECK(one_next + eps / 2 != one_next); | |
83 | ||
84 | // Overflow: | |
85 | BOOST_CHECK_EQUAL(max_val + max_val * eps, inf_val); | |
86 | BOOST_CHECK_EQUAL(-max_val - max_val * eps, -inf_val); | |
87 | BOOST_CHECK_EQUAL(max_val * 2, inf_val); | |
88 | BOOST_CHECK_EQUAL(max_val * -2, -inf_val); | |
89 | BOOST_CHECK_EQUAL(max_val / half, inf_val); | |
90 | BOOST_CHECK_EQUAL(max_val / -half, -inf_val); | |
91 | BOOST_CHECK_EQUAL(max_val / min_val, inf_val); | |
92 | BOOST_CHECK_EQUAL(max_val / -min_val, -inf_val); | |
93 | // Underflow: | |
94 | BOOST_CHECK_EQUAL(min_val * 2 - one_point_5 * min_val, 0); | |
95 | BOOST_CHECK_EQUAL(-min_val * 2 + one_point_5 * min_val, 0); | |
96 | BOOST_CHECK_EQUAL(min_val / 2, 0); | |
97 | BOOST_CHECK_EQUAL(min_val / max_val, 0); | |
98 | BOOST_CHECK_EQUAL(min_val * half, 0); | |
99 | BOOST_CHECK_EQUAL(min_val - min_val, 0); | |
100 | BOOST_CHECK_EQUAL(max_val - max_val, 0); | |
101 | BOOST_CHECK_EQUAL(-min_val + min_val, 0); | |
102 | BOOST_CHECK_EQUAL(-max_val + max_val, 0); | |
103 | // Things which should not over/underflow: | |
104 | BOOST_CHECK_EQUAL((min_val * 2) / 2, min_val); | |
105 | BOOST_CHECK_EQUAL((max_val / 2) * 2, max_val); | |
106 | BOOST_CHECK_GE((min_val * 2.0000001) / 1.9999999999999999, min_val); | |
107 | BOOST_CHECK_LE((max_val / 2.0000001) * 1.9999999999999999, max_val); | |
108 | BOOST_CHECK_EQUAL(min_val * 2 - min_val, min_val); | |
109 | BOOST_CHECK_EQUAL(max_val / 2 + max_val / 2, max_val); | |
110 | // Things involving zero: | |
111 | BOOST_CHECK_EQUAL(max_val + 0, max_val); | |
112 | BOOST_CHECK_EQUAL(max_val - 0, max_val); | |
113 | BOOST_CHECK_EQUAL(0 + max_val, max_val); | |
114 | BOOST_CHECK_EQUAL(0 - max_val, -max_val); | |
115 | BOOST_CHECK_EQUAL(max_val * 0, 0); | |
116 | BOOST_CHECK_EQUAL(0 * max_val, 0); | |
117 | BOOST_CHECK_EQUAL(max_val / 0, inf_val); | |
118 | BOOST_CHECK_EQUAL(0 / max_val, 0); | |
119 | BOOST_CHECK_EQUAL(-max_val / 0, -inf_val); | |
120 | BOOST_CHECK_EQUAL(0 / -max_val, 0); | |
121 | // Things involving infinity: | |
122 | BOOST_CHECK_EQUAL(inf_val + 2, inf_val); | |
123 | BOOST_CHECK_EQUAL(inf_val - 2, inf_val); | |
124 | BOOST_CHECK_EQUAL(inf_val + -2, inf_val); | |
125 | BOOST_CHECK_EQUAL(inf_val - -2, inf_val); | |
126 | BOOST_CHECK_EQUAL(-inf_val + 2, -inf_val); | |
127 | BOOST_CHECK_EQUAL(-inf_val - 2, -inf_val); | |
128 | BOOST_CHECK_EQUAL(-inf_val + -2, -inf_val); | |
129 | BOOST_CHECK_EQUAL(-inf_val - -2, -inf_val); | |
130 | ||
131 | BOOST_CHECK_EQUAL(2 + inf_val, inf_val); | |
132 | BOOST_CHECK_EQUAL(2 - inf_val, -inf_val); | |
133 | BOOST_CHECK_EQUAL(-2 + inf_val, inf_val); | |
134 | BOOST_CHECK_EQUAL(-2 - inf_val, -inf_val); | |
135 | BOOST_CHECK_EQUAL(2 + (-inf_val), -inf_val); | |
136 | BOOST_CHECK_EQUAL(2 - (-inf_val), inf_val); | |
137 | BOOST_CHECK_EQUAL(-2 + (-inf_val), -inf_val); | |
138 | BOOST_CHECK_EQUAL(-2 - (-inf_val), inf_val); | |
139 | ||
140 | BOOST_CHECK_EQUAL(sqrt(inf_val), inf_val); | |
141 | BOOST_CHECK(boost::math::isnan(sqrt(-inf_val))); | |
142 | ||
143 | BOOST_CHECK_EQUAL(inf_val + test_type(2), inf_val); | |
144 | BOOST_CHECK_EQUAL(inf_val - test_type(2), inf_val); | |
145 | BOOST_CHECK_EQUAL(inf_val + test_type(-2), inf_val); | |
146 | BOOST_CHECK_EQUAL(inf_val - test_type(-2), inf_val); | |
147 | BOOST_CHECK_EQUAL(-inf_val + test_type(2), -inf_val); | |
148 | BOOST_CHECK_EQUAL(-inf_val - test_type(2), -inf_val); | |
149 | BOOST_CHECK_EQUAL(-inf_val + test_type(-2), -inf_val); | |
150 | BOOST_CHECK_EQUAL(-inf_val - test_type(-2), -inf_val); | |
151 | ||
152 | BOOST_CHECK_EQUAL(test_type(2) + inf_val, inf_val); | |
153 | BOOST_CHECK_EQUAL(test_type(2) - inf_val, -inf_val); | |
154 | BOOST_CHECK_EQUAL(test_type(-2) + inf_val, inf_val); | |
155 | BOOST_CHECK_EQUAL(test_type(-2) - inf_val, -inf_val); | |
156 | BOOST_CHECK_EQUAL(test_type(2) + (-inf_val), -inf_val); | |
157 | BOOST_CHECK_EQUAL(test_type(2) - (-inf_val), inf_val); | |
158 | BOOST_CHECK_EQUAL(test_type(-2) + (-inf_val), -inf_val); | |
159 | BOOST_CHECK_EQUAL(test_type(-2) - (-inf_val), inf_val); | |
160 | ||
161 | BOOST_CHECK((boost::math::isnan)(inf_val - inf_val)); | |
162 | BOOST_CHECK_EQUAL(inf_val * 2, inf_val); | |
163 | BOOST_CHECK_EQUAL(-inf_val * 2, -inf_val); | |
164 | BOOST_CHECK_EQUAL(inf_val * -2, -inf_val); | |
165 | BOOST_CHECK_EQUAL(-inf_val * -2, inf_val); | |
166 | BOOST_CHECK_EQUAL(inf_val * test_type(-2), -inf_val); | |
167 | BOOST_CHECK_EQUAL(-inf_val * test_type(-2), inf_val); | |
168 | BOOST_CHECK((boost::math::isnan)(inf_val * 0)); | |
169 | BOOST_CHECK((boost::math::isnan)(-inf_val * 0)); | |
170 | BOOST_CHECK_EQUAL(inf_val / 2, inf_val); | |
171 | BOOST_CHECK_EQUAL(-inf_val / 2, -inf_val); | |
172 | BOOST_CHECK_EQUAL(inf_val / -2, -inf_val); | |
173 | BOOST_CHECK_EQUAL(-inf_val / -2, inf_val); | |
174 | BOOST_CHECK_EQUAL(inf_val / test_type(-2), -inf_val); | |
175 | BOOST_CHECK_EQUAL(-inf_val / test_type(-2), inf_val); | |
176 | BOOST_CHECK_EQUAL(inf_val / 0, inf_val); | |
177 | BOOST_CHECK_EQUAL(-inf_val / 0, -inf_val); | |
178 | BOOST_CHECK((boost::math::isnan)(inf_val / inf_val)); | |
179 | BOOST_CHECK((boost::math::isnan)(-inf_val / inf_val)); | |
180 | // Things involving nan: | |
181 | BOOST_CHECK((boost::math::isnan)(nan_val + 2)); | |
182 | BOOST_CHECK((boost::math::isnan)(nan_val - 2)); | |
183 | BOOST_CHECK((boost::math::isnan)(nan_val + 0)); | |
184 | BOOST_CHECK((boost::math::isnan)(nan_val - 0)); | |
185 | BOOST_CHECK((boost::math::isnan)(nan_val + inf_val)); | |
186 | BOOST_CHECK((boost::math::isnan)(nan_val - inf_val)); | |
187 | BOOST_CHECK((boost::math::isnan)(nan_val + nan_val)); | |
188 | BOOST_CHECK((boost::math::isnan)(nan_val - nan_val)); | |
189 | BOOST_CHECK((boost::math::isnan)(2 + nan_val)); | |
190 | BOOST_CHECK((boost::math::isnan)(2 - nan_val)); | |
191 | BOOST_CHECK((boost::math::isnan)(0 - nan_val)); | |
192 | BOOST_CHECK((boost::math::isnan)(0 - nan_val)); | |
193 | BOOST_CHECK((boost::math::isnan)(inf_val + nan_val)); | |
194 | BOOST_CHECK((boost::math::isnan)(inf_val - nan_val)); | |
195 | BOOST_CHECK((boost::math::isnan)(nan_val * 2)); | |
196 | BOOST_CHECK((boost::math::isnan)(nan_val / 2)); | |
197 | BOOST_CHECK((boost::math::isnan)(nan_val * 0)); | |
198 | BOOST_CHECK((boost::math::isnan)(nan_val / 0)); | |
199 | BOOST_CHECK((boost::math::isnan)(nan_val * inf_val)); | |
200 | BOOST_CHECK((boost::math::isnan)(nan_val / inf_val)); | |
201 | BOOST_CHECK((boost::math::isnan)(nan_val * nan_val)); | |
202 | BOOST_CHECK((boost::math::isnan)(nan_val / nan_val)); | |
203 | BOOST_CHECK((boost::math::isnan)(2 * nan_val)); | |
204 | BOOST_CHECK((boost::math::isnan)(2 / nan_val)); | |
205 | BOOST_CHECK((boost::math::isnan)(0 / nan_val)); | |
206 | BOOST_CHECK((boost::math::isnan)(0 / nan_val)); | |
207 | BOOST_CHECK((boost::math::isnan)(inf_val * nan_val)); | |
208 | BOOST_CHECK((boost::math::isnan)(inf_val / nan_val)); | |
209 | // Corner cases: | |
210 | BOOST_CHECK_EQUAL((max_val * half) / half, max_val); | |
211 | BOOST_CHECK_EQUAL((max_val / 2) * 2, max_val); | |
212 | BOOST_CHECK_EQUAL((min_val / half) * half, min_val); | |
213 | BOOST_CHECK_EQUAL((min_val * 2) / 2, min_val); | |
214 | BOOST_CHECK_EQUAL(max_val + min_val, max_val); | |
215 | BOOST_CHECK_EQUAL(min_val + max_val, max_val); | |
216 | BOOST_CHECK_EQUAL(max_val - min_val, max_val); | |
217 | BOOST_CHECK_EQUAL(min_val - max_val, -max_val); | |
218 | // Signed zeros: | |
219 | BOOST_CHECK(boost::math::signbit(min_val * -min_val)); | |
220 | BOOST_CHECK(boost::math::signbit(min_val * min_val) == 0); | |
221 | BOOST_CHECK(boost::math::signbit(-min_val * -min_val) == 0); | |
222 | BOOST_CHECK(boost::math::signbit(-min_val * min_val)); | |
223 | BOOST_CHECK(boost::math::signbit(min_val / max_val) == 0); | |
224 | BOOST_CHECK(boost::math::signbit(min_val / -max_val)); | |
225 | BOOST_CHECK(boost::math::signbit(-min_val / -max_val) == 0); | |
226 | BOOST_CHECK(boost::math::signbit(-min_val / max_val)); | |
227 | BOOST_CHECK(boost::math::signbit(min_val / 2) == 0); | |
228 | BOOST_CHECK(boost::math::signbit(min_val / -2)); | |
229 | BOOST_CHECK(boost::math::signbit(-min_val / -2) == 0); | |
230 | BOOST_CHECK(boost::math::signbit(-min_val / 2)); | |
231 | test_type neg_zero = min_val * -min_val; | |
92f5a8d4 | 232 | test_type zero = 0; |
7c673cae FG |
233 | // Arithmetic involving signed zero: |
234 | BOOST_CHECK_EQUAL(-neg_zero, 0); | |
235 | BOOST_CHECK(!boost::math::signbit(-neg_zero)); | |
236 | BOOST_CHECK_EQUAL(neg_zero + 2, 2); | |
237 | BOOST_CHECK_EQUAL(neg_zero + test_type(2), 2); | |
238 | BOOST_CHECK_EQUAL(2 + neg_zero, 2); | |
239 | BOOST_CHECK_EQUAL(test_type(2) + neg_zero, 2); | |
240 | BOOST_CHECK_EQUAL(neg_zero + -2, -2); | |
241 | BOOST_CHECK_EQUAL(neg_zero + test_type(-2), -2); | |
242 | BOOST_CHECK_EQUAL(-2 + neg_zero, -2); | |
243 | BOOST_CHECK_EQUAL(test_type(-2) + neg_zero, -2); | |
244 | BOOST_CHECK_EQUAL(neg_zero - 2, -2); | |
245 | BOOST_CHECK_EQUAL(neg_zero - test_type(2), -2); | |
246 | BOOST_CHECK_EQUAL(2 - neg_zero, 2); | |
247 | BOOST_CHECK_EQUAL(test_type(2) - neg_zero, 2); | |
248 | BOOST_CHECK_EQUAL(neg_zero - -2, 2); | |
249 | BOOST_CHECK_EQUAL(neg_zero - test_type(-2), 2); | |
250 | BOOST_CHECK_EQUAL(-2 - neg_zero, -2); | |
251 | BOOST_CHECK_EQUAL(test_type(-2) - neg_zero, -2); | |
252 | BOOST_CHECK(!boost::math::signbit(test_type(2) + test_type(-2))); | |
253 | BOOST_CHECK(!boost::math::signbit(test_type(2) - test_type(2))); | |
254 | BOOST_CHECK(!boost::math::signbit(test_type(-2) - test_type(-2))); | |
255 | BOOST_CHECK(!boost::math::signbit(test_type(-2) + test_type(2))); | |
256 | BOOST_CHECK(!boost::math::signbit(zero + zero)); | |
257 | BOOST_CHECK(!boost::math::signbit(zero - zero)); | |
258 | BOOST_CHECK(!boost::math::signbit(neg_zero + zero)); | |
259 | BOOST_CHECK(!boost::math::signbit(zero + neg_zero)); | |
260 | BOOST_CHECK(boost::math::signbit(neg_zero + neg_zero)); | |
261 | BOOST_CHECK(boost::math::signbit(neg_zero - zero)); | |
262 | BOOST_CHECK(!boost::math::signbit(zero - neg_zero)); | |
263 | BOOST_CHECK(!boost::math::signbit(neg_zero - neg_zero)); | |
264 | small = 0.25; | |
265 | BOOST_CHECK(!boost::math::signbit(floor(small))); | |
266 | BOOST_CHECK(!boost::math::signbit(round(small))); | |
267 | BOOST_CHECK(!boost::math::signbit(trunc(small))); | |
268 | small = -small; | |
269 | BOOST_CHECK(boost::math::signbit(ceil(small))); | |
270 | BOOST_CHECK(boost::math::signbit(round(small))); | |
271 | BOOST_CHECK(boost::math::signbit(trunc(small))); | |
272 | ||
7c673cae FG |
273 | BOOST_CHECK_EQUAL(neg_zero * 2, 0); |
274 | BOOST_CHECK_EQUAL(neg_zero * test_type(2), 0); | |
275 | BOOST_CHECK_EQUAL(2 * neg_zero, 0); | |
276 | BOOST_CHECK_EQUAL(test_type(2) * neg_zero, 0); | |
277 | BOOST_CHECK_EQUAL(neg_zero * -2, 0); | |
278 | BOOST_CHECK_EQUAL(neg_zero * test_type(-2), 0); | |
279 | BOOST_CHECK_EQUAL(-2 * neg_zero, 0); | |
280 | BOOST_CHECK_EQUAL(test_type(-2) * neg_zero, 0); | |
281 | BOOST_CHECK(boost::math::signbit(neg_zero * 2)); | |
282 | BOOST_CHECK(boost::math::signbit(neg_zero * test_type(2))); | |
283 | BOOST_CHECK(boost::math::signbit(2 * neg_zero)); | |
284 | BOOST_CHECK(boost::math::signbit(test_type(2) * neg_zero)); | |
285 | BOOST_CHECK(!boost::math::signbit(neg_zero * -2)); | |
286 | BOOST_CHECK(!boost::math::signbit(neg_zero * test_type(-2))); | |
287 | BOOST_CHECK(!boost::math::signbit(-2 * neg_zero)); | |
288 | BOOST_CHECK(!boost::math::signbit(test_type(-2) * neg_zero)); | |
289 | ||
290 | BOOST_CHECK_EQUAL(neg_zero / 2, 0); | |
291 | BOOST_CHECK_EQUAL(neg_zero / test_type(2), 0); | |
292 | BOOST_CHECK_EQUAL(2 / neg_zero, -inf_val); | |
293 | BOOST_CHECK_EQUAL(test_type(2) / neg_zero, -inf_val); | |
294 | BOOST_CHECK_EQUAL(neg_zero / -2, 0); | |
295 | BOOST_CHECK_EQUAL(neg_zero / test_type(-2), 0); | |
296 | BOOST_CHECK_EQUAL(-2 / neg_zero, inf_val); | |
297 | BOOST_CHECK_EQUAL(test_type(-2) / neg_zero, inf_val); | |
298 | BOOST_CHECK(boost::math::signbit(neg_zero / 2)); | |
299 | BOOST_CHECK(boost::math::signbit(neg_zero / test_type(2))); | |
300 | BOOST_CHECK(boost::math::signbit(2 / neg_zero)); | |
301 | BOOST_CHECK(boost::math::signbit(test_type(2) / neg_zero)); | |
302 | BOOST_CHECK(!boost::math::signbit(neg_zero / -2)); | |
303 | BOOST_CHECK(!boost::math::signbit(neg_zero / test_type(-2))); | |
304 | BOOST_CHECK(!boost::math::signbit(-2 / neg_zero)); | |
305 | BOOST_CHECK(!boost::math::signbit(test_type(-2) / neg_zero)); | |
306 | ||
307 | BOOST_CHECK(boost::math::signbit(neg_zero.convert_to<double>())); | |
308 | BOOST_CHECK(boost::math::signbit(neg_zero.convert_to<float>())); | |
309 | BOOST_CHECK(boost::math::signbit(neg_zero.convert_to<long double>())); | |
310 | BOOST_CHECK(!boost::math::signbit(zero.convert_to<double>())); | |
311 | BOOST_CHECK(!boost::math::signbit(zero.convert_to<float>())); | |
312 | BOOST_CHECK(!boost::math::signbit(zero.convert_to<long double>())); | |
313 | ||
314 | // Conversions to other types of special values: | |
92f5a8d4 | 315 | if (std::numeric_limits<float>::has_infinity) |
7c673cae FG |
316 | { |
317 | BOOST_CHECK_EQUAL(inf_val.convert_to<float>(), std::numeric_limits<float>::infinity()); | |
318 | BOOST_CHECK_EQUAL((-inf_val).convert_to<float>(), -std::numeric_limits<float>::infinity()); | |
319 | } | |
92f5a8d4 | 320 | if (std::numeric_limits<float>::has_quiet_NaN) |
7c673cae FG |
321 | { |
322 | BOOST_CHECK((boost::math::isnan)(nan_val.convert_to<float>())); | |
323 | } | |
92f5a8d4 | 324 | if (std::numeric_limits<double>::has_infinity) |
7c673cae FG |
325 | { |
326 | BOOST_CHECK_EQUAL(inf_val.convert_to<double>(), std::numeric_limits<double>::infinity()); | |
327 | BOOST_CHECK_EQUAL((-inf_val).convert_to<double>(), -std::numeric_limits<double>::infinity()); | |
328 | } | |
92f5a8d4 | 329 | if (std::numeric_limits<double>::has_quiet_NaN) |
7c673cae FG |
330 | { |
331 | BOOST_CHECK((boost::math::isnan)(nan_val.convert_to<double>())); | |
332 | } | |
92f5a8d4 | 333 | if (std::numeric_limits<long double>::has_infinity) |
7c673cae FG |
334 | { |
335 | BOOST_CHECK_EQUAL(inf_val.convert_to<long double>(), std::numeric_limits<long double>::infinity()); | |
336 | BOOST_CHECK_EQUAL((-inf_val).convert_to<long double>(), -std::numeric_limits<long double>::infinity()); | |
337 | } | |
92f5a8d4 | 338 | if (std::numeric_limits<long double>::has_quiet_NaN) |
7c673cae FG |
339 | { |
340 | BOOST_CHECK((boost::math::isnan)(nan_val.convert_to<long double>())); | |
341 | } | |
b32b8144 FG |
342 | // |
343 | // Bug https://svn.boost.org/trac/boost/attachment/ticket/12580 | |
344 | // | |
345 | using std::ldexp; | |
346 | test_type a(1); | |
347 | test_type b = ldexp(test_type(0.99), -std::numeric_limits<test_type>::digits); | |
348 | good_type ga(1); | |
349 | good_type gb = ldexp(good_type(0.99), -std::numeric_limits<good_type>::digits); | |
350 | BOOST_CHECK_EQUAL(good_type(test_type(a - b)), good_type(ga - gb)); | |
351 | BOOST_CHECK_EQUAL(good_type(test_type(b - a)), good_type(gb - ga)); | |
352 | BOOST_CHECK_EQUAL(good_type(test_type(a + b)), good_type(ga + gb)); | |
353 | BOOST_CHECK_EQUAL(good_type(test_type(b + a)), good_type(gb + ga)); | |
354 | ||
355 | BOOST_CHECK_EQUAL(good_type(test_type(a - -b)), good_type(ga - -gb)); | |
356 | BOOST_CHECK_EQUAL(good_type(test_type(b - -a)), good_type(gb - -ga)); | |
357 | BOOST_CHECK_EQUAL(good_type(test_type(a + -b)), good_type(ga + -gb)); | |
358 | BOOST_CHECK_EQUAL(good_type(test_type(b + -a)), good_type(gb + -ga)); | |
359 | ||
360 | BOOST_CHECK_EQUAL(good_type(test_type(-a - b)), good_type(-ga - gb)); | |
361 | BOOST_CHECK_EQUAL(good_type(test_type(-b - a)), good_type(-gb - ga)); | |
362 | BOOST_CHECK_EQUAL(good_type(test_type(-a + b)), good_type(-ga + gb)); | |
363 | BOOST_CHECK_EQUAL(good_type(test_type(-b + a)), good_type(-gb + ga)); | |
364 | ||
365 | BOOST_CHECK_EQUAL(good_type(test_type(-a - -b)), good_type(-ga - -gb)); | |
366 | BOOST_CHECK_EQUAL(good_type(test_type(-b - -a)), good_type(-gb - -ga)); | |
367 | BOOST_CHECK_EQUAL(good_type(test_type(-a + -b)), good_type(-ga + -gb)); | |
368 | BOOST_CHECK_EQUAL(good_type(test_type(-b + -a)), good_type(-gb + -ga)); | |
369 | ||
92f5a8d4 | 370 | b = ldexp(test_type(0.5), -std::numeric_limits<test_type>::digits); |
b32b8144 FG |
371 | gb = ldexp(good_type(0.5), -std::numeric_limits<good_type>::digits); |
372 | BOOST_CHECK_EQUAL(good_type(test_type(a - b)), good_type(ga - gb)); | |
373 | BOOST_CHECK_EQUAL(good_type(test_type(b - a)), good_type(gb - ga)); | |
374 | BOOST_CHECK_EQUAL(good_type(test_type(a + b)), good_type(ga + gb)); | |
375 | BOOST_CHECK_EQUAL(good_type(test_type(b + a)), good_type(gb + ga)); | |
376 | ||
377 | BOOST_CHECK_EQUAL(good_type(test_type(a - -b)), good_type(ga - -gb)); | |
378 | BOOST_CHECK_EQUAL(good_type(test_type(b - -a)), good_type(gb - -ga)); | |
379 | BOOST_CHECK_EQUAL(good_type(test_type(a + -b)), good_type(ga + -gb)); | |
380 | BOOST_CHECK_EQUAL(good_type(test_type(b + -a)), good_type(gb + -ga)); | |
381 | ||
382 | BOOST_CHECK_EQUAL(good_type(test_type(-a - b)), good_type(-ga - gb)); | |
383 | BOOST_CHECK_EQUAL(good_type(test_type(-b - a)), good_type(-gb - ga)); | |
384 | BOOST_CHECK_EQUAL(good_type(test_type(-a + b)), good_type(-ga + gb)); | |
385 | BOOST_CHECK_EQUAL(good_type(test_type(-b + a)), good_type(-gb + ga)); | |
386 | ||
387 | BOOST_CHECK_EQUAL(good_type(test_type(-a - -b)), good_type(-ga - -gb)); | |
388 | BOOST_CHECK_EQUAL(good_type(test_type(-b - -a)), good_type(-gb - -ga)); | |
389 | BOOST_CHECK_EQUAL(good_type(test_type(-a + -b)), good_type(-ga + -gb)); | |
390 | BOOST_CHECK_EQUAL(good_type(test_type(-b + -a)), good_type(-gb + -ga)); | |
391 | ||
92f5a8d4 | 392 | b = ldexp(test_type(1), -std::numeric_limits<test_type>::digits); |
b32b8144 FG |
393 | gb = ldexp(good_type(1), -std::numeric_limits<good_type>::digits); |
394 | BOOST_CHECK_EQUAL(good_type(test_type(a - b)), good_type(ga - gb)); | |
395 | BOOST_CHECK_EQUAL(good_type(test_type(b - a)), good_type(gb - ga)); | |
396 | BOOST_CHECK_EQUAL(good_type(test_type(a + b)), good_type(ga + gb)); | |
397 | BOOST_CHECK_EQUAL(good_type(test_type(b + a)), good_type(gb + ga)); | |
398 | ||
399 | BOOST_CHECK_EQUAL(good_type(test_type(a - -b)), good_type(ga - -gb)); | |
400 | BOOST_CHECK_EQUAL(good_type(test_type(b - -a)), good_type(gb - -ga)); | |
401 | BOOST_CHECK_EQUAL(good_type(test_type(a + -b)), good_type(ga + -gb)); | |
402 | BOOST_CHECK_EQUAL(good_type(test_type(b + -a)), good_type(gb + -ga)); | |
403 | ||
404 | BOOST_CHECK_EQUAL(good_type(test_type(-a - b)), good_type(-ga - gb)); | |
405 | BOOST_CHECK_EQUAL(good_type(test_type(-b - a)), good_type(-gb - ga)); | |
406 | BOOST_CHECK_EQUAL(good_type(test_type(-a + b)), good_type(-ga + gb)); | |
407 | BOOST_CHECK_EQUAL(good_type(test_type(-b + a)), good_type(-gb + ga)); | |
408 | ||
409 | BOOST_CHECK_EQUAL(good_type(test_type(-a - -b)), good_type(-ga - -gb)); | |
410 | BOOST_CHECK_EQUAL(good_type(test_type(-b - -a)), good_type(-gb - -ga)); | |
411 | BOOST_CHECK_EQUAL(good_type(test_type(-a + -b)), good_type(-ga + -gb)); | |
412 | BOOST_CHECK_EQUAL(good_type(test_type(-b + -a)), good_type(-gb + -ga)); | |
413 | ||
92f5a8d4 | 414 | b = ldexp(test_type(0.50000000001), -std::numeric_limits<test_type>::digits); |
b32b8144 FG |
415 | gb = ldexp(good_type(0.50000000001), -std::numeric_limits<good_type>::digits); |
416 | BOOST_CHECK_EQUAL(good_type(test_type(a - b)), good_type(ga - gb)); | |
417 | BOOST_CHECK_EQUAL(good_type(test_type(b - a)), good_type(gb - ga)); | |
418 | BOOST_CHECK_EQUAL(good_type(test_type(a + b)), good_type(ga + gb)); | |
419 | BOOST_CHECK_EQUAL(good_type(test_type(b + a)), good_type(gb + ga)); | |
420 | ||
421 | BOOST_CHECK_EQUAL(good_type(test_type(a - -b)), good_type(ga - -gb)); | |
422 | BOOST_CHECK_EQUAL(good_type(test_type(b - -a)), good_type(gb - -ga)); | |
423 | BOOST_CHECK_EQUAL(good_type(test_type(a + -b)), good_type(ga + -gb)); | |
424 | BOOST_CHECK_EQUAL(good_type(test_type(b + -a)), good_type(gb + -ga)); | |
425 | ||
426 | BOOST_CHECK_EQUAL(good_type(test_type(-a - b)), good_type(-ga - gb)); | |
427 | BOOST_CHECK_EQUAL(good_type(test_type(-b - a)), good_type(-gb - ga)); | |
428 | BOOST_CHECK_EQUAL(good_type(test_type(-a + b)), good_type(-ga + gb)); | |
429 | BOOST_CHECK_EQUAL(good_type(test_type(-b + a)), good_type(-gb + ga)); | |
430 | ||
431 | BOOST_CHECK_EQUAL(good_type(test_type(-a - -b)), good_type(-ga - -gb)); | |
432 | BOOST_CHECK_EQUAL(good_type(test_type(-b - -a)), good_type(-gb - -ga)); | |
433 | BOOST_CHECK_EQUAL(good_type(test_type(-a + -b)), good_type(-ga + -gb)); | |
434 | BOOST_CHECK_EQUAL(good_type(test_type(-b + -a)), good_type(-gb + -ga)); | |
435 | ||
92f5a8d4 | 436 | a = a + ldexp(a, -20); |
b32b8144 FG |
437 | ga = ga + ldexp(ga, -20); |
438 | BOOST_CHECK_EQUAL(good_type(test_type(a - b)), good_type(ga - gb)); | |
439 | BOOST_CHECK_EQUAL(good_type(test_type(b - a)), good_type(gb - ga)); | |
440 | BOOST_CHECK_EQUAL(good_type(test_type(a + b)), good_type(ga + gb)); | |
441 | BOOST_CHECK_EQUAL(good_type(test_type(b + a)), good_type(gb + ga)); | |
442 | ||
443 | BOOST_CHECK_EQUAL(good_type(test_type(a - -b)), good_type(ga - -gb)); | |
444 | BOOST_CHECK_EQUAL(good_type(test_type(b - -a)), good_type(gb - -ga)); | |
445 | BOOST_CHECK_EQUAL(good_type(test_type(a + -b)), good_type(ga + -gb)); | |
446 | BOOST_CHECK_EQUAL(good_type(test_type(b + -a)), good_type(gb + -ga)); | |
447 | ||
448 | BOOST_CHECK_EQUAL(good_type(test_type(-a - b)), good_type(-ga - gb)); | |
449 | BOOST_CHECK_EQUAL(good_type(test_type(-b - a)), good_type(-gb - ga)); | |
450 | BOOST_CHECK_EQUAL(good_type(test_type(-a + b)), good_type(-ga + gb)); | |
451 | BOOST_CHECK_EQUAL(good_type(test_type(-b + a)), good_type(-gb + ga)); | |
452 | ||
453 | BOOST_CHECK_EQUAL(good_type(test_type(-a - -b)), good_type(-ga - -gb)); | |
454 | BOOST_CHECK_EQUAL(good_type(test_type(-b - -a)), good_type(-gb - -ga)); | |
455 | BOOST_CHECK_EQUAL(good_type(test_type(-a + -b)), good_type(-ga + -gb)); | |
456 | BOOST_CHECK_EQUAL(good_type(test_type(-b + -a)), good_type(-gb + -ga)); | |
457 | ||
92f5a8d4 | 458 | b = ldexp(test_type(0.5), -std::numeric_limits<test_type>::digits); |
b32b8144 FG |
459 | gb = ldexp(good_type(0.5), -std::numeric_limits<good_type>::digits); |
460 | BOOST_CHECK_EQUAL(good_type(test_type(a - b)), good_type(ga - gb)); | |
461 | BOOST_CHECK_EQUAL(good_type(test_type(b - a)), good_type(gb - ga)); | |
462 | BOOST_CHECK_EQUAL(good_type(test_type(a + b)), good_type(ga + gb)); | |
463 | BOOST_CHECK_EQUAL(good_type(test_type(b + a)), good_type(gb + ga)); | |
464 | ||
465 | BOOST_CHECK_EQUAL(good_type(test_type(a - -b)), good_type(ga - -gb)); | |
466 | BOOST_CHECK_EQUAL(good_type(test_type(b - -a)), good_type(gb - -ga)); | |
467 | BOOST_CHECK_EQUAL(good_type(test_type(a + -b)), good_type(ga + -gb)); | |
468 | BOOST_CHECK_EQUAL(good_type(test_type(b + -a)), good_type(gb + -ga)); | |
469 | ||
470 | BOOST_CHECK_EQUAL(good_type(test_type(-a - b)), good_type(-ga - gb)); | |
471 | BOOST_CHECK_EQUAL(good_type(test_type(-b - a)), good_type(-gb - ga)); | |
472 | BOOST_CHECK_EQUAL(good_type(test_type(-a + b)), good_type(-ga + gb)); | |
473 | BOOST_CHECK_EQUAL(good_type(test_type(-b + a)), good_type(-gb + ga)); | |
474 | ||
475 | BOOST_CHECK_EQUAL(good_type(test_type(-a - -b)), good_type(-ga - -gb)); | |
476 | BOOST_CHECK_EQUAL(good_type(test_type(-b - -a)), good_type(-gb - -ga)); | |
477 | BOOST_CHECK_EQUAL(good_type(test_type(-a + -b)), good_type(-ga + -gb)); | |
478 | BOOST_CHECK_EQUAL(good_type(test_type(-b + -a)), good_type(-gb + -ga)); | |
479 | ||
92f5a8d4 | 480 | b = ldexp(test_type(1), -std::numeric_limits<test_type>::digits); |
b32b8144 FG |
481 | gb = ldexp(good_type(1), -std::numeric_limits<good_type>::digits); |
482 | BOOST_CHECK_EQUAL(good_type(test_type(a - b)), good_type(ga - gb)); | |
483 | BOOST_CHECK_EQUAL(good_type(test_type(b - a)), good_type(gb - ga)); | |
484 | BOOST_CHECK_EQUAL(good_type(test_type(a + b)), good_type(ga + gb)); | |
485 | BOOST_CHECK_EQUAL(good_type(test_type(b + a)), good_type(gb + ga)); | |
486 | ||
487 | BOOST_CHECK_EQUAL(good_type(test_type(a - -b)), good_type(ga - -gb)); | |
488 | BOOST_CHECK_EQUAL(good_type(test_type(b - -a)), good_type(gb - -ga)); | |
489 | BOOST_CHECK_EQUAL(good_type(test_type(a + -b)), good_type(ga + -gb)); | |
490 | BOOST_CHECK_EQUAL(good_type(test_type(b + -a)), good_type(gb + -ga)); | |
491 | ||
492 | BOOST_CHECK_EQUAL(good_type(test_type(-a - b)), good_type(-ga - gb)); | |
493 | BOOST_CHECK_EQUAL(good_type(test_type(-b - a)), good_type(-gb - ga)); | |
494 | BOOST_CHECK_EQUAL(good_type(test_type(-a + b)), good_type(-ga + gb)); | |
495 | BOOST_CHECK_EQUAL(good_type(test_type(-b + a)), good_type(-gb + ga)); | |
496 | ||
497 | BOOST_CHECK_EQUAL(good_type(test_type(-a - -b)), good_type(-ga - -gb)); | |
498 | BOOST_CHECK_EQUAL(good_type(test_type(-b - -a)), good_type(-gb - -ga)); | |
499 | BOOST_CHECK_EQUAL(good_type(test_type(-a + -b)), good_type(-ga + -gb)); | |
500 | BOOST_CHECK_EQUAL(good_type(test_type(-b + -a)), good_type(-gb + -ga)); | |
501 | ||
92f5a8d4 | 502 | b = ldexp(test_type(0.50000000001), -std::numeric_limits<test_type>::digits); |
b32b8144 FG |
503 | gb = ldexp(good_type(0.50000000001), -std::numeric_limits<good_type>::digits); |
504 | BOOST_CHECK_EQUAL(good_type(test_type(a - b)), good_type(ga - gb)); | |
505 | BOOST_CHECK_EQUAL(good_type(test_type(b - a)), good_type(gb - ga)); | |
506 | BOOST_CHECK_EQUAL(good_type(test_type(a + b)), good_type(ga + gb)); | |
507 | BOOST_CHECK_EQUAL(good_type(test_type(b + a)), good_type(gb + ga)); | |
508 | ||
509 | BOOST_CHECK_EQUAL(good_type(test_type(a - -b)), good_type(ga - -gb)); | |
510 | BOOST_CHECK_EQUAL(good_type(test_type(b - -a)), good_type(gb - -ga)); | |
511 | BOOST_CHECK_EQUAL(good_type(test_type(a + -b)), good_type(ga + -gb)); | |
512 | BOOST_CHECK_EQUAL(good_type(test_type(b + -a)), good_type(gb + -ga)); | |
513 | ||
514 | BOOST_CHECK_EQUAL(good_type(test_type(-a - b)), good_type(-ga - gb)); | |
515 | BOOST_CHECK_EQUAL(good_type(test_type(-b - a)), good_type(-gb - ga)); | |
516 | BOOST_CHECK_EQUAL(good_type(test_type(-a + b)), good_type(-ga + gb)); | |
517 | BOOST_CHECK_EQUAL(good_type(test_type(-b + a)), good_type(-gb + ga)); | |
518 | ||
519 | BOOST_CHECK_EQUAL(good_type(test_type(-a - -b)), good_type(-ga - -gb)); | |
520 | BOOST_CHECK_EQUAL(good_type(test_type(-b - -a)), good_type(-gb - -ga)); | |
521 | BOOST_CHECK_EQUAL(good_type(test_type(-a + -b)), good_type(-ga + -gb)); | |
522 | BOOST_CHECK_EQUAL(good_type(test_type(-b + -a)), good_type(-gb + -ga)); | |
523 | ||
92f5a8d4 TL |
524 | a = 1; |
525 | a = boost::math::float_prior(a); | |
b32b8144 FG |
526 | ga = 1; |
527 | ga = boost::math::float_prior(ga); | |
528 | BOOST_CHECK_EQUAL(good_type(test_type(a - b)), good_type(ga - gb)); | |
529 | BOOST_CHECK_EQUAL(good_type(test_type(b - a)), good_type(gb - ga)); | |
530 | BOOST_CHECK_EQUAL(good_type(test_type(a + b)), good_type(ga + gb)); | |
531 | BOOST_CHECK_EQUAL(good_type(test_type(b + a)), good_type(gb + ga)); | |
532 | ||
533 | BOOST_CHECK_EQUAL(good_type(test_type(a - -b)), good_type(ga - -gb)); | |
534 | BOOST_CHECK_EQUAL(good_type(test_type(b - -a)), good_type(gb - -ga)); | |
535 | BOOST_CHECK_EQUAL(good_type(test_type(a + -b)), good_type(ga + -gb)); | |
536 | BOOST_CHECK_EQUAL(good_type(test_type(b + -a)), good_type(gb + -ga)); | |
537 | ||
538 | BOOST_CHECK_EQUAL(good_type(test_type(-a - b)), good_type(-ga - gb)); | |
539 | BOOST_CHECK_EQUAL(good_type(test_type(-b - a)), good_type(-gb - ga)); | |
540 | BOOST_CHECK_EQUAL(good_type(test_type(-a + b)), good_type(-ga + gb)); | |
541 | BOOST_CHECK_EQUAL(good_type(test_type(-b + a)), good_type(-gb + ga)); | |
542 | ||
543 | BOOST_CHECK_EQUAL(good_type(test_type(-a - -b)), good_type(-ga - -gb)); | |
544 | BOOST_CHECK_EQUAL(good_type(test_type(-b - -a)), good_type(-gb - -ga)); | |
545 | BOOST_CHECK_EQUAL(good_type(test_type(-a + -b)), good_type(-ga + -gb)); | |
546 | BOOST_CHECK_EQUAL(good_type(test_type(-b + -a)), good_type(-gb + -ga)); | |
547 | ||
92f5a8d4 | 548 | b = ldexp(test_type(0.5), -std::numeric_limits<test_type>::digits); |
b32b8144 FG |
549 | gb = ldexp(good_type(0.5), -std::numeric_limits<good_type>::digits); |
550 | BOOST_CHECK_EQUAL(good_type(test_type(a - b)), good_type(ga - gb)); | |
551 | BOOST_CHECK_EQUAL(good_type(test_type(b - a)), good_type(gb - ga)); | |
552 | BOOST_CHECK_EQUAL(good_type(test_type(a + b)), good_type(ga + gb)); | |
553 | BOOST_CHECK_EQUAL(good_type(test_type(b + a)), good_type(gb + ga)); | |
554 | ||
555 | BOOST_CHECK_EQUAL(good_type(test_type(a - -b)), good_type(ga - -gb)); | |
556 | BOOST_CHECK_EQUAL(good_type(test_type(b - -a)), good_type(gb - -ga)); | |
557 | BOOST_CHECK_EQUAL(good_type(test_type(a + -b)), good_type(ga + -gb)); | |
558 | BOOST_CHECK_EQUAL(good_type(test_type(b + -a)), good_type(gb + -ga)); | |
559 | ||
560 | BOOST_CHECK_EQUAL(good_type(test_type(-a - b)), good_type(-ga - gb)); | |
561 | BOOST_CHECK_EQUAL(good_type(test_type(-b - a)), good_type(-gb - ga)); | |
562 | BOOST_CHECK_EQUAL(good_type(test_type(-a + b)), good_type(-ga + gb)); | |
563 | BOOST_CHECK_EQUAL(good_type(test_type(-b + a)), good_type(-gb + ga)); | |
564 | ||
565 | BOOST_CHECK_EQUAL(good_type(test_type(-a - -b)), good_type(-ga - -gb)); | |
566 | BOOST_CHECK_EQUAL(good_type(test_type(-b - -a)), good_type(-gb - -ga)); | |
567 | BOOST_CHECK_EQUAL(good_type(test_type(-a + -b)), good_type(-ga + -gb)); | |
568 | BOOST_CHECK_EQUAL(good_type(test_type(-b + -a)), good_type(-gb + -ga)); | |
569 | ||
92f5a8d4 | 570 | b = ldexp(test_type(1), -std::numeric_limits<test_type>::digits); |
b32b8144 FG |
571 | gb = ldexp(good_type(1), -std::numeric_limits<good_type>::digits); |
572 | BOOST_CHECK_EQUAL(good_type(test_type(a - b)), good_type(ga - gb)); | |
573 | BOOST_CHECK_EQUAL(good_type(test_type(b - a)), good_type(gb - ga)); | |
574 | BOOST_CHECK_EQUAL(good_type(test_type(a + b)), good_type(ga + gb)); | |
575 | BOOST_CHECK_EQUAL(good_type(test_type(b + a)), good_type(gb + ga)); | |
576 | ||
577 | BOOST_CHECK_EQUAL(good_type(test_type(a - -b)), good_type(ga - -gb)); | |
578 | BOOST_CHECK_EQUAL(good_type(test_type(b - -a)), good_type(gb - -ga)); | |
579 | BOOST_CHECK_EQUAL(good_type(test_type(a + -b)), good_type(ga + -gb)); | |
580 | BOOST_CHECK_EQUAL(good_type(test_type(b + -a)), good_type(gb + -ga)); | |
581 | ||
582 | BOOST_CHECK_EQUAL(good_type(test_type(-a - b)), good_type(-ga - gb)); | |
583 | BOOST_CHECK_EQUAL(good_type(test_type(-b - a)), good_type(-gb - ga)); | |
584 | BOOST_CHECK_EQUAL(good_type(test_type(-a + b)), good_type(-ga + gb)); | |
585 | BOOST_CHECK_EQUAL(good_type(test_type(-b + a)), good_type(-gb + ga)); | |
586 | ||
587 | BOOST_CHECK_EQUAL(good_type(test_type(-a - -b)), good_type(-ga - -gb)); | |
588 | BOOST_CHECK_EQUAL(good_type(test_type(-b - -a)), good_type(-gb - -ga)); | |
589 | BOOST_CHECK_EQUAL(good_type(test_type(-a + -b)), good_type(-ga + -gb)); | |
590 | BOOST_CHECK_EQUAL(good_type(test_type(-b + -a)), good_type(-gb + -ga)); | |
591 | ||
92f5a8d4 | 592 | b = ldexp(test_type(0.50000000001), -std::numeric_limits<test_type>::digits); |
b32b8144 FG |
593 | gb = ldexp(good_type(0.50000000001), -std::numeric_limits<good_type>::digits); |
594 | BOOST_CHECK_EQUAL(good_type(test_type(a - b)), good_type(ga - gb)); | |
595 | BOOST_CHECK_EQUAL(good_type(test_type(b - a)), good_type(gb - ga)); | |
596 | BOOST_CHECK_EQUAL(good_type(test_type(a + b)), good_type(ga + gb)); | |
597 | BOOST_CHECK_EQUAL(good_type(test_type(b + a)), good_type(gb + ga)); | |
598 | ||
599 | BOOST_CHECK_EQUAL(good_type(test_type(a - -b)), good_type(ga - -gb)); | |
600 | BOOST_CHECK_EQUAL(good_type(test_type(b - -a)), good_type(gb - -ga)); | |
601 | BOOST_CHECK_EQUAL(good_type(test_type(a + -b)), good_type(ga + -gb)); | |
602 | BOOST_CHECK_EQUAL(good_type(test_type(b + -a)), good_type(gb + -ga)); | |
20effc67 TL |
603 | |
604 | BOOST_CHECK_EQUAL(good_type(test_type(-a - b)), good_type(-ga - gb)); | |
605 | BOOST_CHECK_EQUAL(good_type(test_type(-b - a)), good_type(-gb - ga)); | |
606 | BOOST_CHECK_EQUAL(good_type(test_type(-a + b)), good_type(-ga + gb)); | |
607 | BOOST_CHECK_EQUAL(good_type(test_type(-b + a)), good_type(-gb + ga)); | |
608 | ||
609 | BOOST_CHECK_EQUAL(good_type(test_type(-a - -b)), good_type(-ga - -gb)); | |
610 | BOOST_CHECK_EQUAL(good_type(test_type(-b - -a)), good_type(-gb - -ga)); | |
611 | BOOST_CHECK_EQUAL(good_type(test_type(-a + -b)), good_type(-ga + -gb)); | |
612 | BOOST_CHECK_EQUAL(good_type(test_type(-b + -a)), good_type(-gb + -ga)); | |
613 | ||
614 | a = boost::math::float_next(test_type(1)); | |
615 | ga = boost::math::float_next(good_type(1)); | |
616 | b = ldexp(boost::math::float_prior(test_type(1)), -std::numeric_limits<test_type>::digits); | |
617 | gb = ldexp(boost::math::float_prior(good_type(1)), -std::numeric_limits<test_type>::digits); | |
618 | BOOST_CHECK_EQUAL(good_type(test_type(a - b)), good_type(ga - gb)); | |
619 | BOOST_CHECK_EQUAL(good_type(test_type(b - a)), good_type(gb - ga)); | |
620 | BOOST_CHECK_EQUAL(good_type(test_type(a + b)), good_type(ga + gb)); | |
621 | BOOST_CHECK_EQUAL(good_type(test_type(b + a)), good_type(gb + ga)); | |
622 | ||
623 | BOOST_CHECK_EQUAL(good_type(test_type(a - -b)), good_type(ga - -gb)); | |
624 | BOOST_CHECK_EQUAL(good_type(test_type(b - -a)), good_type(gb - -ga)); | |
625 | BOOST_CHECK_EQUAL(good_type(test_type(a + -b)), good_type(ga + -gb)); | |
626 | BOOST_CHECK_EQUAL(good_type(test_type(b + -a)), good_type(gb + -ga)); | |
627 | ||
628 | BOOST_CHECK_EQUAL(good_type(test_type(-a - b)), good_type(-ga - gb)); | |
629 | BOOST_CHECK_EQUAL(good_type(test_type(-b - a)), good_type(-gb - ga)); | |
630 | BOOST_CHECK_EQUAL(good_type(test_type(-a + b)), good_type(-ga + gb)); | |
631 | BOOST_CHECK_EQUAL(good_type(test_type(-b + a)), good_type(-gb + ga)); | |
632 | ||
633 | BOOST_CHECK_EQUAL(good_type(test_type(-a - -b)), good_type(-ga - -gb)); | |
634 | BOOST_CHECK_EQUAL(good_type(test_type(-b - -a)), good_type(-gb - -ga)); | |
635 | BOOST_CHECK_EQUAL(good_type(test_type(-a + -b)), good_type(-ga + -gb)); | |
636 | BOOST_CHECK_EQUAL(good_type(test_type(-b + -a)), good_type(-gb + -ga)); | |
637 | ||
638 | b = ldexp(b, -1); | |
639 | gb = ldexp(gb, -1); | |
640 | BOOST_CHECK_EQUAL(good_type(test_type(a - b)), good_type(ga - gb)); | |
641 | BOOST_CHECK_EQUAL(good_type(test_type(b - a)), good_type(gb - ga)); | |
642 | BOOST_CHECK_EQUAL(good_type(test_type(a + b)), good_type(ga + gb)); | |
643 | BOOST_CHECK_EQUAL(good_type(test_type(b + a)), good_type(gb + ga)); | |
644 | ||
645 | BOOST_CHECK_EQUAL(good_type(test_type(a - -b)), good_type(ga - -gb)); | |
646 | BOOST_CHECK_EQUAL(good_type(test_type(b - -a)), good_type(gb - -ga)); | |
647 | BOOST_CHECK_EQUAL(good_type(test_type(a + -b)), good_type(ga + -gb)); | |
648 | BOOST_CHECK_EQUAL(good_type(test_type(b + -a)), good_type(gb + -ga)); | |
649 | ||
650 | BOOST_CHECK_EQUAL(good_type(test_type(-a - b)), good_type(-ga - gb)); | |
651 | BOOST_CHECK_EQUAL(good_type(test_type(-b - a)), good_type(-gb - ga)); | |
652 | BOOST_CHECK_EQUAL(good_type(test_type(-a + b)), good_type(-ga + gb)); | |
653 | BOOST_CHECK_EQUAL(good_type(test_type(-b + a)), good_type(-gb + ga)); | |
654 | ||
655 | BOOST_CHECK_EQUAL(good_type(test_type(-a - -b)), good_type(-ga - -gb)); | |
656 | BOOST_CHECK_EQUAL(good_type(test_type(-b - -a)), good_type(-gb - -ga)); | |
657 | BOOST_CHECK_EQUAL(good_type(test_type(-a + -b)), good_type(-ga + -gb)); | |
658 | BOOST_CHECK_EQUAL(good_type(test_type(-b + -a)), good_type(-gb + -ga)); | |
659 | ||
660 | a = 1.75; // even mantissa, not a power of 2 | |
661 | ga = 1.75; | |
662 | b = ldexp(test_type(1), -std::numeric_limits<test_type>::digits); | |
663 | gb = ldexp(good_type(1), -std::numeric_limits<test_type>::digits); | |
664 | BOOST_CHECK_EQUAL(good_type(test_type(a - b)), good_type(ga - gb)); | |
665 | BOOST_CHECK_EQUAL(good_type(test_type(b - a)), good_type(gb - ga)); | |
666 | BOOST_CHECK_EQUAL(good_type(test_type(a + b)), good_type(ga + gb)); | |
667 | BOOST_CHECK_EQUAL(good_type(test_type(b + a)), good_type(gb + ga)); | |
668 | ||
669 | BOOST_CHECK_EQUAL(good_type(test_type(a - -b)), good_type(ga - -gb)); | |
670 | BOOST_CHECK_EQUAL(good_type(test_type(b - -a)), good_type(gb - -ga)); | |
671 | BOOST_CHECK_EQUAL(good_type(test_type(a + -b)), good_type(ga + -gb)); | |
672 | BOOST_CHECK_EQUAL(good_type(test_type(b + -a)), good_type(gb + -ga)); | |
673 | ||
674 | BOOST_CHECK_EQUAL(good_type(test_type(-a - b)), good_type(-ga - gb)); | |
675 | BOOST_CHECK_EQUAL(good_type(test_type(-b - a)), good_type(-gb - ga)); | |
676 | BOOST_CHECK_EQUAL(good_type(test_type(-a + b)), good_type(-ga + gb)); | |
677 | BOOST_CHECK_EQUAL(good_type(test_type(-b + a)), good_type(-gb + ga)); | |
678 | ||
679 | BOOST_CHECK_EQUAL(good_type(test_type(-a - -b)), good_type(-ga - -gb)); | |
680 | BOOST_CHECK_EQUAL(good_type(test_type(-b - -a)), good_type(-gb - -ga)); | |
681 | BOOST_CHECK_EQUAL(good_type(test_type(-a + -b)), good_type(-ga + -gb)); | |
682 | BOOST_CHECK_EQUAL(good_type(test_type(-b + -a)), good_type(-gb + -ga)); | |
683 | b = ldexp(b, -1); | |
684 | gb = ldexp(gb, -1); | |
685 | BOOST_CHECK_EQUAL(good_type(test_type(a - b)), good_type(ga - gb)); | |
686 | BOOST_CHECK_EQUAL(good_type(test_type(b - a)), good_type(gb - ga)); | |
687 | BOOST_CHECK_EQUAL(good_type(test_type(a + b)), good_type(ga + gb)); | |
688 | BOOST_CHECK_EQUAL(good_type(test_type(b + a)), good_type(gb + ga)); | |
689 | ||
690 | BOOST_CHECK_EQUAL(good_type(test_type(a - -b)), good_type(ga - -gb)); | |
691 | BOOST_CHECK_EQUAL(good_type(test_type(b - -a)), good_type(gb - -ga)); | |
692 | BOOST_CHECK_EQUAL(good_type(test_type(a + -b)), good_type(ga + -gb)); | |
693 | BOOST_CHECK_EQUAL(good_type(test_type(b + -a)), good_type(gb + -ga)); | |
694 | ||
695 | BOOST_CHECK_EQUAL(good_type(test_type(-a - b)), good_type(-ga - gb)); | |
696 | BOOST_CHECK_EQUAL(good_type(test_type(-b - a)), good_type(-gb - ga)); | |
697 | BOOST_CHECK_EQUAL(good_type(test_type(-a + b)), good_type(-ga + gb)); | |
698 | BOOST_CHECK_EQUAL(good_type(test_type(-b + a)), good_type(-gb + ga)); | |
699 | ||
700 | BOOST_CHECK_EQUAL(good_type(test_type(-a - -b)), good_type(-ga - -gb)); | |
701 | BOOST_CHECK_EQUAL(good_type(test_type(-b - -a)), good_type(-gb - -ga)); | |
702 | BOOST_CHECK_EQUAL(good_type(test_type(-a + -b)), good_type(-ga + -gb)); | |
703 | BOOST_CHECK_EQUAL(good_type(test_type(-b + -a)), good_type(-gb + -ga)); | |
704 | ||
705 | b = ldexp(boost::math::float_prior(test_type(1)), -std::numeric_limits<test_type>::digits); | |
706 | gb = ldexp(boost::math::float_prior(good_type(1)), -std::numeric_limits<test_type>::digits); | |
707 | BOOST_CHECK_EQUAL(good_type(test_type(a - b)), good_type(ga - gb)); | |
708 | BOOST_CHECK_EQUAL(good_type(test_type(b - a)), good_type(gb - ga)); | |
709 | BOOST_CHECK_EQUAL(good_type(test_type(a + b)), good_type(ga + gb)); | |
710 | BOOST_CHECK_EQUAL(good_type(test_type(b + a)), good_type(gb + ga)); | |
711 | ||
712 | BOOST_CHECK_EQUAL(good_type(test_type(a - -b)), good_type(ga - -gb)); | |
713 | BOOST_CHECK_EQUAL(good_type(test_type(b - -a)), good_type(gb - -ga)); | |
714 | BOOST_CHECK_EQUAL(good_type(test_type(a + -b)), good_type(ga + -gb)); | |
715 | BOOST_CHECK_EQUAL(good_type(test_type(b + -a)), good_type(gb + -ga)); | |
716 | ||
717 | BOOST_CHECK_EQUAL(good_type(test_type(-a - b)), good_type(-ga - gb)); | |
718 | BOOST_CHECK_EQUAL(good_type(test_type(-b - a)), good_type(-gb - ga)); | |
719 | BOOST_CHECK_EQUAL(good_type(test_type(-a + b)), good_type(-ga + gb)); | |
720 | BOOST_CHECK_EQUAL(good_type(test_type(-b + a)), good_type(-gb + ga)); | |
721 | ||
722 | BOOST_CHECK_EQUAL(good_type(test_type(-a - -b)), good_type(-ga - -gb)); | |
723 | BOOST_CHECK_EQUAL(good_type(test_type(-b - -a)), good_type(-gb - -ga)); | |
724 | BOOST_CHECK_EQUAL(good_type(test_type(-a + -b)), good_type(-ga + -gb)); | |
725 | BOOST_CHECK_EQUAL(good_type(test_type(-b + -a)), good_type(-gb + -ga)); | |
726 | ||
727 | b = ldexp(b, -1); | |
728 | gb = ldexp(gb, -1); | |
729 | BOOST_CHECK_EQUAL(good_type(test_type(a - b)), good_type(ga - gb)); | |
730 | BOOST_CHECK_EQUAL(good_type(test_type(b - a)), good_type(gb - ga)); | |
731 | BOOST_CHECK_EQUAL(good_type(test_type(a + b)), good_type(ga + gb)); | |
732 | BOOST_CHECK_EQUAL(good_type(test_type(b + a)), good_type(gb + ga)); | |
733 | ||
734 | BOOST_CHECK_EQUAL(good_type(test_type(a - -b)), good_type(ga - -gb)); | |
735 | BOOST_CHECK_EQUAL(good_type(test_type(b - -a)), good_type(gb - -ga)); | |
736 | BOOST_CHECK_EQUAL(good_type(test_type(a + -b)), good_type(ga + -gb)); | |
737 | BOOST_CHECK_EQUAL(good_type(test_type(b + -a)), good_type(gb + -ga)); | |
738 | ||
739 | BOOST_CHECK_EQUAL(good_type(test_type(-a - b)), good_type(-ga - gb)); | |
740 | BOOST_CHECK_EQUAL(good_type(test_type(-b - a)), good_type(-gb - ga)); | |
741 | BOOST_CHECK_EQUAL(good_type(test_type(-a + b)), good_type(-ga + gb)); | |
742 | BOOST_CHECK_EQUAL(good_type(test_type(-b + a)), good_type(-gb + ga)); | |
743 | ||
744 | BOOST_CHECK_EQUAL(good_type(test_type(-a - -b)), good_type(-ga - -gb)); | |
745 | BOOST_CHECK_EQUAL(good_type(test_type(-b - -a)), good_type(-gb - -ga)); | |
746 | BOOST_CHECK_EQUAL(good_type(test_type(-a + -b)), good_type(-ga + -gb)); | |
747 | BOOST_CHECK_EQUAL(good_type(test_type(-b + -a)), good_type(-gb + -ga)); | |
748 | ||
749 | b = ldexp(test_type(0.75), -std::numeric_limits<test_type>::digits); // even mantissa not a power of 2. | |
750 | gb = ldexp(good_type(0.75), -std::numeric_limits<test_type>::digits); | |
751 | BOOST_CHECK_EQUAL(good_type(test_type(a - b)), good_type(ga - gb)); | |
752 | BOOST_CHECK_EQUAL(good_type(test_type(b - a)), good_type(gb - ga)); | |
753 | BOOST_CHECK_EQUAL(good_type(test_type(a + b)), good_type(ga + gb)); | |
754 | BOOST_CHECK_EQUAL(good_type(test_type(b + a)), good_type(gb + ga)); | |
755 | ||
756 | BOOST_CHECK_EQUAL(good_type(test_type(a - -b)), good_type(ga - -gb)); | |
757 | BOOST_CHECK_EQUAL(good_type(test_type(b - -a)), good_type(gb - -ga)); | |
758 | BOOST_CHECK_EQUAL(good_type(test_type(a + -b)), good_type(ga + -gb)); | |
759 | BOOST_CHECK_EQUAL(good_type(test_type(b + -a)), good_type(gb + -ga)); | |
760 | ||
761 | BOOST_CHECK_EQUAL(good_type(test_type(-a - b)), good_type(-ga - gb)); | |
762 | BOOST_CHECK_EQUAL(good_type(test_type(-b - a)), good_type(-gb - ga)); | |
763 | BOOST_CHECK_EQUAL(good_type(test_type(-a + b)), good_type(-ga + gb)); | |
764 | BOOST_CHECK_EQUAL(good_type(test_type(-b + a)), good_type(-gb + ga)); | |
765 | ||
766 | BOOST_CHECK_EQUAL(good_type(test_type(-a - -b)), good_type(-ga - -gb)); | |
767 | BOOST_CHECK_EQUAL(good_type(test_type(-b - -a)), good_type(-gb - -ga)); | |
768 | BOOST_CHECK_EQUAL(good_type(test_type(-a + -b)), good_type(-ga + -gb)); | |
769 | BOOST_CHECK_EQUAL(good_type(test_type(-b + -a)), good_type(-gb + -ga)); | |
770 | ||
771 | b = ldexp(b, -1); | |
772 | gb = ldexp(gb, -1); | |
773 | BOOST_CHECK_EQUAL(good_type(test_type(a - b)), good_type(ga - gb)); | |
774 | BOOST_CHECK_EQUAL(good_type(test_type(b - a)), good_type(gb - ga)); | |
775 | BOOST_CHECK_EQUAL(good_type(test_type(a + b)), good_type(ga + gb)); | |
776 | BOOST_CHECK_EQUAL(good_type(test_type(b + a)), good_type(gb + ga)); | |
777 | ||
778 | BOOST_CHECK_EQUAL(good_type(test_type(a - -b)), good_type(ga - -gb)); | |
779 | BOOST_CHECK_EQUAL(good_type(test_type(b - -a)), good_type(gb - -ga)); | |
780 | BOOST_CHECK_EQUAL(good_type(test_type(a + -b)), good_type(ga + -gb)); | |
781 | BOOST_CHECK_EQUAL(good_type(test_type(b + -a)), good_type(gb + -ga)); | |
b32b8144 FG |
782 | |
783 | BOOST_CHECK_EQUAL(good_type(test_type(-a - b)), good_type(-ga - gb)); | |
784 | BOOST_CHECK_EQUAL(good_type(test_type(-b - a)), good_type(-gb - ga)); | |
785 | BOOST_CHECK_EQUAL(good_type(test_type(-a + b)), good_type(-ga + gb)); | |
786 | BOOST_CHECK_EQUAL(good_type(test_type(-b + a)), good_type(-gb + ga)); | |
787 | ||
788 | BOOST_CHECK_EQUAL(good_type(test_type(-a - -b)), good_type(-ga - -gb)); | |
789 | BOOST_CHECK_EQUAL(good_type(test_type(-b - -a)), good_type(-gb - -ga)); | |
790 | BOOST_CHECK_EQUAL(good_type(test_type(-a + -b)), good_type(-ga + -gb)); | |
791 | BOOST_CHECK_EQUAL(good_type(test_type(-b + -a)), good_type(-gb + -ga)); | |
7c673cae FG |
792 | } |
793 | ||
794 | int main() | |
795 | { | |
796 | test_special_cases(); | |
797 | unsigned error_count = 0; | |
92f5a8d4 | 798 | for (unsigned i = 0; i < 100000; ++i) |
7c673cae FG |
799 | { |
800 | good_type a = generate_random<good_type>(); | |
801 | good_type b = generate_random<good_type>(); | |
802 | test_type ta(a); | |
803 | test_type tb(b); | |
804 | ||
805 | BOOST_CHECK_EQUAL(test_type(a * b), ta * tb); | |
806 | BOOST_CHECK_EQUAL(test_type(-a * b), -ta * tb); | |
807 | BOOST_CHECK_EQUAL(test_type(a * -b), ta * -tb); | |
808 | BOOST_CHECK_EQUAL(test_type(-a * -b), -ta * -tb); | |
809 | ||
810 | BOOST_CHECK_EQUAL(test_type(a + b), ta + tb); | |
811 | BOOST_CHECK_EQUAL(test_type(-a + b), -ta + tb); | |
812 | BOOST_CHECK_EQUAL(test_type(a + -b), ta + -tb); | |
813 | BOOST_CHECK_EQUAL(test_type(-a + -b), -ta + -tb); | |
814 | ||
815 | BOOST_CHECK_EQUAL(test_type(a - b), ta - tb); | |
816 | BOOST_CHECK_EQUAL(test_type(-a - b), -ta - tb); | |
817 | BOOST_CHECK_EQUAL(test_type(a - -b), ta - -tb); | |
818 | BOOST_CHECK_EQUAL(test_type(-a - -b), -ta - -tb); | |
819 | ||
820 | BOOST_CHECK_EQUAL(test_type(a / b), ta / tb); | |
821 | BOOST_CHECK_EQUAL(test_type(-a / b), -ta / tb); | |
822 | BOOST_CHECK_EQUAL(test_type(a / -b), ta / -tb); | |
823 | BOOST_CHECK_EQUAL(test_type(-a / -b), -ta / -tb); | |
824 | ||
825 | BOOST_CHECK_EQUAL(test_type(sqrt(a)), sqrt(ta)); | |
826 | BOOST_CHECK_EQUAL(test_type(floor(a)), floor(ta)); | |
827 | BOOST_CHECK_EQUAL(test_type(floor(-a)), floor(-ta)); | |
828 | BOOST_CHECK_EQUAL(test_type(ceil(a)), ceil(ta)); | |
829 | BOOST_CHECK_EQUAL(test_type(ceil(-a)), ceil(-ta)); | |
830 | ||
831 | #ifdef TEST_MPFR | |
832 | // | |
833 | // Conversions: | |
834 | // | |
835 | BOOST_CHECK_EQUAL(a.convert_to<double>(), ta.convert_to<double>()); | |
836 | BOOST_CHECK_EQUAL(a.convert_to<float>(), ta.convert_to<float>()); | |
837 | BOOST_CHECK_EQUAL(b.convert_to<double>(), tb.convert_to<double>()); | |
838 | BOOST_CHECK_EQUAL(b.convert_to<float>(), tb.convert_to<float>()); | |
839 | #else | |
840 | BOOST_CHECK_EQUAL(a, ta.convert_to<double>()); | |
841 | BOOST_CHECK_EQUAL(static_cast<float>(a), ta.convert_to<float>()); | |
842 | BOOST_CHECK_EQUAL(b, tb.convert_to<double>()); | |
843 | BOOST_CHECK_EQUAL(static_cast<float>(b), tb.convert_to<float>()); | |
844 | #endif | |
845 | ||
846 | static boost::random::mt19937 i_gen; | |
847 | ||
848 | int si = i_gen(); | |
849 | BOOST_CHECK_EQUAL(test_type(a * si), ta * si); | |
850 | BOOST_CHECK_EQUAL(test_type(-a * si), -ta * si); | |
851 | BOOST_CHECK_EQUAL(test_type(-a * -si), -ta * -si); | |
852 | BOOST_CHECK_EQUAL(test_type(a * -si), ta * -si); | |
853 | unsigned ui = std::abs(si); | |
854 | BOOST_CHECK_EQUAL(test_type(a * ui), ta * ui); | |
855 | BOOST_CHECK_EQUAL(test_type(-a * ui), -ta * ui); | |
856 | ||
857 | // Divide: | |
858 | BOOST_CHECK_EQUAL(test_type(a / si), ta / si); | |
859 | BOOST_CHECK_EQUAL(test_type(-a / si), -ta / si); | |
860 | BOOST_CHECK_EQUAL(test_type(-a / -si), -ta / -si); | |
861 | BOOST_CHECK_EQUAL(test_type(a / -si), ta / -si); | |
862 | BOOST_CHECK_EQUAL(test_type(a / ui), ta / ui); | |
863 | BOOST_CHECK_EQUAL(test_type(-a / ui), -ta / ui); | |
864 | // Error reporting: | |
f67539c2 | 865 | if ((unsigned)boost::detail::test_errors() != error_count) |
7c673cae FG |
866 | { |
867 | error_count = boost::detail::test_errors(); | |
868 | std::cout << std::setprecision(std::numeric_limits<test_type>::max_digits10) << std::scientific; | |
869 | std::cout << "a (mpfr) = " << a << std::endl; | |
870 | std::cout << "a (test) = " << ta << std::endl; | |
871 | std::cout << "b (mpfr) = " << b << std::endl; | |
872 | std::cout << "b (test) = " << tb << std::endl; | |
873 | std::cout << "si = " << si << std::endl; | |
874 | std::cout << "ui = " << ui << std::endl; | |
875 | } | |
876 | } | |
877 | return boost::report_errors(); | |
878 | } |