Imported Upstream version 1.72.0
[platform/upstream/boost.git] / libs / multiprecision / test / test_cpp_bin_float.cpp
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
9 #define _SCL_SECURE_NO_WARNINGS
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 {
25    typedef int                   e_type;
26    static boost::random::mt19937 gen;
27    T                             val      = gen();
28    T                             prev_val = -1;
29    while (val != prev_val)
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
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 {
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;
58    test_type one_point_5 = 1.5;
59
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
69    if (std::numeric_limits<test_type>::has_denorm)
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;
77    small           = ldexp(small, -std::numeric_limits<test_type>::digits);
78    BOOST_CHECK(test_type(1) + small != test_type(1));
79    // And if we increment 1.0 first, then an even smaller
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;
232    test_type zero     = 0;
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
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:
315    if (std::numeric_limits<float>::has_infinity)
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    }
320    if (std::numeric_limits<float>::has_quiet_NaN)
321    {
322       BOOST_CHECK((boost::math::isnan)(nan_val.convert_to<float>()));
323    }
324    if (std::numeric_limits<double>::has_infinity)
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    }
329    if (std::numeric_limits<double>::has_quiet_NaN)
330    {
331       BOOST_CHECK((boost::math::isnan)(nan_val.convert_to<double>()));
332    }
333    if (std::numeric_limits<long double>::has_infinity)
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    }
338    if (std::numeric_limits<long double>::has_quiet_NaN)
339    {
340       BOOST_CHECK((boost::math::isnan)(nan_val.convert_to<long double>()));
341    }
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
370    b  = ldexp(test_type(0.5), -std::numeric_limits<test_type>::digits);
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
392    b  = ldexp(test_type(1), -std::numeric_limits<test_type>::digits);
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
414    b  = ldexp(test_type(0.50000000001), -std::numeric_limits<test_type>::digits);
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
436    a  = a + ldexp(a, -20);
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
458    b  = ldexp(test_type(0.5), -std::numeric_limits<test_type>::digits);
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
480    b  = ldexp(test_type(1), -std::numeric_limits<test_type>::digits);
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
502    b  = ldexp(test_type(0.50000000001), -std::numeric_limits<test_type>::digits);
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
524    a  = 1;
525    a  = boost::math::float_prior(a);
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
548    b  = ldexp(test_type(0.5), -std::numeric_limits<test_type>::digits);
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
570    b  = ldexp(test_type(1), -std::numeric_limits<test_type>::digits);
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
592    b  = ldexp(test_type(0.50000000001), -std::numeric_limits<test_type>::digits);
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));
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
615 int main()
616 {
617    test_special_cases();
618    unsigned error_count = 0;
619    for (unsigned i = 0; i < 100000; ++i)
620    {
621       good_type a = generate_random<good_type>();
622       good_type b = generate_random<good_type>();
623       test_type ta(a);
624       test_type tb(b);
625
626       BOOST_CHECK_EQUAL(test_type(a * b), ta * tb);
627       BOOST_CHECK_EQUAL(test_type(-a * b), -ta * tb);
628       BOOST_CHECK_EQUAL(test_type(a * -b), ta * -tb);
629       BOOST_CHECK_EQUAL(test_type(-a * -b), -ta * -tb);
630
631       BOOST_CHECK_EQUAL(test_type(a + b), ta + tb);
632       BOOST_CHECK_EQUAL(test_type(-a + b), -ta + tb);
633       BOOST_CHECK_EQUAL(test_type(a + -b), ta + -tb);
634       BOOST_CHECK_EQUAL(test_type(-a + -b), -ta + -tb);
635
636       BOOST_CHECK_EQUAL(test_type(a - b), ta - tb);
637       BOOST_CHECK_EQUAL(test_type(-a - b), -ta - tb);
638       BOOST_CHECK_EQUAL(test_type(a - -b), ta - -tb);
639       BOOST_CHECK_EQUAL(test_type(-a - -b), -ta - -tb);
640
641       BOOST_CHECK_EQUAL(test_type(a / b), ta / tb);
642       BOOST_CHECK_EQUAL(test_type(-a / b), -ta / tb);
643       BOOST_CHECK_EQUAL(test_type(a / -b), ta / -tb);
644       BOOST_CHECK_EQUAL(test_type(-a / -b), -ta / -tb);
645
646       BOOST_CHECK_EQUAL(test_type(sqrt(a)), sqrt(ta));
647       BOOST_CHECK_EQUAL(test_type(floor(a)), floor(ta));
648       BOOST_CHECK_EQUAL(test_type(floor(-a)), floor(-ta));
649       BOOST_CHECK_EQUAL(test_type(ceil(a)), ceil(ta));
650       BOOST_CHECK_EQUAL(test_type(ceil(-a)), ceil(-ta));
651
652 #ifdef TEST_MPFR
653       //
654       // Conversions:
655       //
656       BOOST_CHECK_EQUAL(a.convert_to<double>(), ta.convert_to<double>());
657       BOOST_CHECK_EQUAL(a.convert_to<float>(), ta.convert_to<float>());
658       BOOST_CHECK_EQUAL(b.convert_to<double>(), tb.convert_to<double>());
659       BOOST_CHECK_EQUAL(b.convert_to<float>(), tb.convert_to<float>());
660 #else
661       BOOST_CHECK_EQUAL(a, ta.convert_to<double>());
662       BOOST_CHECK_EQUAL(static_cast<float>(a), ta.convert_to<float>());
663       BOOST_CHECK_EQUAL(b, tb.convert_to<double>());
664       BOOST_CHECK_EQUAL(static_cast<float>(b), tb.convert_to<float>());
665 #endif
666
667       static boost::random::mt19937 i_gen;
668
669       int si = i_gen();
670       BOOST_CHECK_EQUAL(test_type(a * si), ta * si);
671       BOOST_CHECK_EQUAL(test_type(-a * si), -ta * si);
672       BOOST_CHECK_EQUAL(test_type(-a * -si), -ta * -si);
673       BOOST_CHECK_EQUAL(test_type(a * -si), ta * -si);
674       unsigned ui = std::abs(si);
675       BOOST_CHECK_EQUAL(test_type(a * ui), ta * ui);
676       BOOST_CHECK_EQUAL(test_type(-a * ui), -ta * ui);
677
678       // Divide:
679       BOOST_CHECK_EQUAL(test_type(a / si), ta / si);
680       BOOST_CHECK_EQUAL(test_type(-a / si), -ta / si);
681       BOOST_CHECK_EQUAL(test_type(-a / -si), -ta / -si);
682       BOOST_CHECK_EQUAL(test_type(a / -si), ta / -si);
683       BOOST_CHECK_EQUAL(test_type(a / ui), ta / ui);
684       BOOST_CHECK_EQUAL(test_type(-a / ui), -ta / ui);
685       // Error reporting:
686       if (boost::detail::test_errors() != error_count)
687       {
688          error_count = boost::detail::test_errors();
689          std::cout << std::setprecision(std::numeric_limits<test_type>::max_digits10) << std::scientific;
690          std::cout << "a (mpfr) = " << a << std::endl;
691          std::cout << "a (test) = " << ta << std::endl;
692          std::cout << "b (mpfr) = " << b << std::endl;
693          std::cout << "b (test) = " << tb << std::endl;
694          std::cout << "si       = " << si << std::endl;
695          std::cout << "ui       = " << ui << std::endl;
696       }
697    }
698    return boost::report_errors();
699 }