1 ///////////////////////////////////////////////////////////////
2 //  Copyright 2012 John Maddock. Distributed under the Boost
3 //  Software License, Version 1.0. (See accompanying file
4 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_
5 
6 #ifdef TEST_VLD
7 #include <vld.h>
8 #endif
9 
10 #include <boost/math/special_functions/pow.hpp>
11 #include <boost/math/common_factor_rt.hpp>
12 #include "test.hpp"
13 
14 template <class T>
15 struct is_boost_rational : public boost::mpl::false_{};
16 
17 #ifdef BOOST_MSVC
18 // warning C4127: conditional expression is constant
19 #pragma warning(disable:4127)
20 #endif
21 
22 template <class Target, class Source>
23 Target checked_lexical_cast(const Source& val)
24 {
25    try
26    {
27       return boost::lexical_cast<Target>(val);
28    }
29    catch(...)
30    {
31       std::cerr << "Error in lexical cast\nSource type = " << typeid(Source).name() << " \"" << val << "\"\n";
32       std::cerr << "Target type = " << typeid(Target).name() << std::endl;
33       throw;
34    }
35 }
36 
37 
isfloat(float)38 bool isfloat(float){ return true; }
isfloat(double)39 bool isfloat(double){ return true; }
isfloat(long double)40 bool isfloat(long double){ return true; }
isfloat(T)41 template <class T> bool isfloat(T){ return false; }
42 
43 namespace detail{
44 
45 template<class tag, class Arg1, class Arg2, class Arg3, class Arg4>
46 typename boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type
abs(boost::multiprecision::detail::expression<tag,Arg1,Arg2,Arg3,Arg4> const & v)47    abs(boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4> const& v)
48 {
49    typedef typename boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type result_type;
50    return v < 0 ? result_type(-v) : result_type(v);
51 }
52 
53 }
54 
55 template <class T>
56 struct is_twos_complement_integer : public boost::mpl::true_ {};
57 
58 template <class T>
59 struct related_type
60 {
61    typedef T type;
62 };
63 
64 template <class Real, class Val>
test_comparisons(Val,Val,const boost::mpl::false_)65 void test_comparisons(Val, Val, const boost::mpl::false_)
66 {}
67 
normalize_compare_result(int r)68 int normalize_compare_result(int r)
69 {
70    return r > 0 ? 1 : r < 0 ? -1 : 0;
71 }
72 
73 template <class Real, class Val>
test_comparisons(Val a,Val b,const boost::mpl::true_)74 void test_comparisons(Val a, Val b, const boost::mpl::true_)
75 {
76    Real r1(a);
77    Real r2(b);
78    Real z(1);
79 
80    int cr = a < b ? -1 : a > b ? 1 : 0;
81 
82    BOOST_CHECK_EQUAL(r1 == r2, a == b);
83    BOOST_CHECK_EQUAL(r1 != r2, a != b);
84    BOOST_CHECK_EQUAL(r1 <= r2, a <= b);
85    BOOST_CHECK_EQUAL(r1 < r2, a < b);
86    BOOST_CHECK_EQUAL(r1 >= r2, a >= b);
87    BOOST_CHECK_EQUAL(r1 > r2, a > b);
88 
89    BOOST_CHECK_EQUAL(r1 == b, a == b);
90    BOOST_CHECK_EQUAL(r1 != b, a != b);
91    BOOST_CHECK_EQUAL(r1 <= b, a <= b);
92    BOOST_CHECK_EQUAL(r1 < b, a < b);
93    BOOST_CHECK_EQUAL(r1 >= b, a >= b);
94    BOOST_CHECK_EQUAL(r1 > b, a > b);
95 
96    BOOST_CHECK_EQUAL(a == r2, a == b);
97    BOOST_CHECK_EQUAL(a != r2, a != b);
98    BOOST_CHECK_EQUAL(a <= r2, a <= b);
99    BOOST_CHECK_EQUAL(a < r2, a < b);
100    BOOST_CHECK_EQUAL(a >= r2, a >= b);
101    BOOST_CHECK_EQUAL(a > r2, a > b);
102 
103    BOOST_CHECK_EQUAL(r1*z == r2, a == b);
104    BOOST_CHECK_EQUAL(r1*z != r2, a != b);
105    BOOST_CHECK_EQUAL(r1*z <= r2, a <= b);
106    BOOST_CHECK_EQUAL(r1*z < r2, a < b);
107    BOOST_CHECK_EQUAL(r1*z >= r2, a >= b);
108    BOOST_CHECK_EQUAL(r1*z > r2, a > b);
109 
110    BOOST_CHECK_EQUAL(r1 == r2*z, a == b);
111    BOOST_CHECK_EQUAL(r1 != r2*z, a != b);
112    BOOST_CHECK_EQUAL(r1 <= r2*z, a <= b);
113    BOOST_CHECK_EQUAL(r1 < r2*z, a < b);
114    BOOST_CHECK_EQUAL(r1 >= r2*z, a >= b);
115    BOOST_CHECK_EQUAL(r1 > r2*z, a > b);
116 
117    BOOST_CHECK_EQUAL(r1*z == r2*z, a == b);
118    BOOST_CHECK_EQUAL(r1*z != r2*z, a != b);
119    BOOST_CHECK_EQUAL(r1*z <= r2*z, a <= b);
120    BOOST_CHECK_EQUAL(r1*z < r2*z, a < b);
121    BOOST_CHECK_EQUAL(r1*z >= r2*z, a >= b);
122    BOOST_CHECK_EQUAL(r1*z > r2*z, a > b);
123 
124    BOOST_CHECK_EQUAL(r1*z == b, a == b);
125    BOOST_CHECK_EQUAL(r1*z != b, a != b);
126    BOOST_CHECK_EQUAL(r1*z <= b, a <= b);
127    BOOST_CHECK_EQUAL(r1*z < b, a < b);
128    BOOST_CHECK_EQUAL(r1*z >= b, a >= b);
129    BOOST_CHECK_EQUAL(r1*z > b, a > b);
130 
131    BOOST_CHECK_EQUAL(a == r2*z, a == b);
132    BOOST_CHECK_EQUAL(a != r2*z, a != b);
133    BOOST_CHECK_EQUAL(a <= r2*z, a <= b);
134    BOOST_CHECK_EQUAL(a < r2*z, a < b);
135    BOOST_CHECK_EQUAL(a >= r2*z, a >= b);
136    BOOST_CHECK_EQUAL(a > r2*z, a > b);
137 
138    BOOST_CHECK_EQUAL(normalize_compare_result(r1.compare(r2)), cr);
139    BOOST_CHECK_EQUAL(normalize_compare_result(r2.compare(r1)), -cr);
140    BOOST_CHECK_EQUAL(normalize_compare_result(r1.compare(b)), cr);
141    BOOST_CHECK_EQUAL(normalize_compare_result(r2.compare(a)), -cr);
142 }
143 
144 template <class Real, class Exp>
test_conditional(Real v,Exp e)145 void test_conditional(Real v, Exp e)
146 {
147    //
148    // Verify that Exp is usable in Boolean contexts, and has the same value as v:
149    //
150    if(e)
151    {
152       BOOST_CHECK(v);
153    }
154    else
155    {
156       BOOST_CHECK(!v);
157    }
158    if(!e)
159    {
160       BOOST_CHECK(!v);
161    }
162    else
163    {
164       BOOST_CHECK(v);
165    }
166 }
167 
168 template <class Real>
test_complement(Real a,Real b,Real c,const boost::mpl::true_ &)169 void test_complement(Real a, Real b, Real c, const boost::mpl::true_&)
170 {
171    int i = 1020304;
172    int j = 56789123;
173    int sign_mask = ~0;
174    if(std::numeric_limits<Real>::is_signed)
175    {
176       BOOST_CHECK_EQUAL(~a ,  (~i & sign_mask));
177       c = a & ~b;
178       BOOST_CHECK_EQUAL(c ,  (i & (~j & sign_mask)));
179       c = ~(a | b);
180       BOOST_CHECK_EQUAL(c ,  (~(i | j) & sign_mask));
181    }
182    else
183    {
184       BOOST_CHECK_EQUAL((~a & a) ,  0);
185    }
186 }
187 
188 template <class Real>
test_complement(Real,Real,Real,const boost::mpl::false_ &)189 void test_complement(Real, Real, Real, const boost::mpl::false_&)
190 {
191 }
192 
193 template <class Real, class T>
test_integer_ops(const T &)194 void test_integer_ops(const T&){}
195 
196 template <class Real>
test_rational(const boost::mpl::true_ &)197 void test_rational(const boost::mpl::true_&)
198 {
199    Real a(2);
200    a /= 3;
201    BOOST_CHECK_EQUAL(numerator(a) ,  2);
202    BOOST_CHECK_EQUAL(denominator(a) ,  3);
203    Real b(4);
204    b /= 6;
205    BOOST_CHECK_EQUAL(a ,  b);
206 
207    //
208    // Check IO code:
209    //
210    std::stringstream ss;
211    ss << a;
212    ss >> b;
213    BOOST_CHECK_EQUAL(a, b);
214 }
215 
216 template <class Real>
test_rational(const boost::mpl::false_ &)217 void test_rational(const boost::mpl::false_&)
218 {
219    Real a(2);
220    a /= 3;
221    BOOST_CHECK_EQUAL(numerator(a) ,  2);
222    BOOST_CHECK_EQUAL(denominator(a) ,  3);
223    Real b(4);
224    b /= 6;
225    BOOST_CHECK_EQUAL(a ,  b);
226 
227    BOOST_CHECK_THROW(Real(a / 0), std::overflow_error);
228    BOOST_CHECK_THROW(Real("3.14"), std::runtime_error);
229    b = Real("2/3");
230    BOOST_CHECK_EQUAL(a, b);
231    //
232    // Check IO code:
233    //
234    std::stringstream ss;
235    ss << a;
236    ss >> b;
237    BOOST_CHECK_EQUAL(a, b);
238 }
239 
240 template <class Real>
test_integer_ops(const boost::mpl::int_<boost::multiprecision::number_kind_rational> &)241 void test_integer_ops(const boost::mpl::int_<boost::multiprecision::number_kind_rational>&)
242 {
243    test_rational<Real>(is_boost_rational<Real>());
244 }
245 
246 template <class Real>
test_signed_integer_ops(const boost::mpl::true_ &)247 void test_signed_integer_ops(const boost::mpl::true_&)
248 {
249    Real a(20);
250    Real b(7);
251    Real c(5);
252    BOOST_CHECK_EQUAL(-a % c ,  0);
253    BOOST_CHECK_EQUAL(-a % b ,  -20 % 7);
254    BOOST_CHECK_EQUAL(-a % -b ,  -20 % -7);
255    BOOST_CHECK_EQUAL(a % -b ,  20 % -7);
256    BOOST_CHECK_EQUAL(-a % 7 ,  -20 % 7);
257    BOOST_CHECK_EQUAL(-a % -7 ,  -20 % -7);
258    BOOST_CHECK_EQUAL(a % -7 ,  20 % -7);
259    BOOST_CHECK_EQUAL(-a % 7u ,  -20 % 7);
260    BOOST_CHECK_EQUAL(-a % a ,  0);
261    BOOST_CHECK_EQUAL(-a % 5 ,  0);
262    BOOST_CHECK_EQUAL(-a % -5 ,  0);
263    BOOST_CHECK_EQUAL(a % -5 ,  0);
264 
265    b = -b;
266    BOOST_CHECK_EQUAL(a % b ,  20 % -7);
267    a = -a;
268    BOOST_CHECK_EQUAL(a % b ,  -20 % -7);
269    BOOST_CHECK_EQUAL(a % -7 ,  -20 % -7);
270    b = 7;
271    BOOST_CHECK_EQUAL(a % b ,  -20 % 7);
272    BOOST_CHECK_EQUAL(a % 7 ,  -20 % 7);
273    BOOST_CHECK_EQUAL(a % 7u ,  -20 % 7);
274 
275    a = 20;
276    a %= b;
277    BOOST_CHECK_EQUAL(a ,  20 % 7);
278    a = -20;
279    a %= b;
280    BOOST_CHECK_EQUAL(a ,  -20 % 7);
281    a = 20;
282    a %= -b;
283    BOOST_CHECK_EQUAL(a ,  20 % -7);
284    a = -20;
285    a %= -b;
286    BOOST_CHECK_EQUAL(a ,  -20 % -7);
287    a = 5;
288    a %= b - a;
289    BOOST_CHECK_EQUAL(a ,  5 % (7-5));
290    a = -20;
291    a %= 7;
292    BOOST_CHECK_EQUAL(a ,  -20 % 7);
293    a = 20;
294    a %= -7;
295    BOOST_CHECK_EQUAL(a ,  20 % -7);
296    a = -20;
297    a %= -7;
298    BOOST_CHECK_EQUAL(a ,  -20 % -7);
299 #ifndef BOOST_NO_LONG_LONG
300    a = -20;
301    a %= 7uLL;
302    BOOST_CHECK_EQUAL(a ,  -20 % 7);
303    a = 20;
304    a %= -7LL;
305    BOOST_CHECK_EQUAL(a ,  20 % -7);
306    a = -20;
307    a %= -7LL;
308    BOOST_CHECK_EQUAL(a ,  -20 % -7);
309 #endif
310    a = 400;
311    b = 45;
312    BOOST_CHECK_EQUAL(gcd(a, -45) ,  boost::math::gcd(400, 45));
313    BOOST_CHECK_EQUAL(lcm(a, -45) ,  boost::math::lcm(400, 45));
314    BOOST_CHECK_EQUAL(gcd(-400, b) ,  boost::math::gcd(400, 45));
315    BOOST_CHECK_EQUAL(lcm(-400, b) ,  boost::math::lcm(400, 45));
316    a = -20;
317    BOOST_CHECK_EQUAL(abs(a) ,  20);
318    BOOST_CHECK_EQUAL(abs(-a) ,  20);
319    BOOST_CHECK_EQUAL(abs(+a) ,  20);
320    a = 20;
321    BOOST_CHECK_EQUAL(abs(a) ,  20);
322    BOOST_CHECK_EQUAL(abs(-a) ,  20);
323    BOOST_CHECK_EQUAL(abs(+a) ,  20);
324    a = -400;
325    b = 45;
326    BOOST_CHECK_EQUAL(gcd(a, b) ,  boost::math::gcd(-400, 45));
327    BOOST_CHECK_EQUAL(lcm(a, b) ,  boost::math::lcm(-400, 45));
328    BOOST_CHECK_EQUAL(gcd(a, 45) ,  boost::math::gcd(-400, 45));
329    BOOST_CHECK_EQUAL(lcm(a, 45) ,  boost::math::lcm(-400, 45));
330    BOOST_CHECK_EQUAL(gcd(-400, b) ,  boost::math::gcd(-400, 45));
331    BOOST_CHECK_EQUAL(lcm(-400, b) ,  boost::math::lcm(-400, 45));
332    Real r;
333    divide_qr(a, b, c, r);
334    BOOST_CHECK_EQUAL(c ,  a / b);
335    BOOST_CHECK_EQUAL(r ,  a % b);
336    BOOST_CHECK_EQUAL(integer_modulus(a, 57) ,  abs(a % 57));
337    b = -57;
338    divide_qr(a, b, c, r);
339    BOOST_CHECK_EQUAL(c ,  a / b);
340    BOOST_CHECK_EQUAL(r ,  a % b);
341    BOOST_CHECK_EQUAL(integer_modulus(a, -57) ,  abs(a % -57));
342    a = 458;
343    divide_qr(a, b, c, r);
344    BOOST_CHECK_EQUAL(c ,  a / b);
345    BOOST_CHECK_EQUAL(r ,  a % b);
346    BOOST_CHECK_EQUAL(integer_modulus(a, -57) ,  abs(a % -57));
347 }
348 template <class Real>
test_signed_integer_ops(const boost::mpl::false_ &)349 void test_signed_integer_ops(const boost::mpl::false_&)
350 {
351 }
352 
353 template <class Real>
test_integer_ops(const boost::mpl::int_<boost::multiprecision::number_kind_integer> &)354 void test_integer_ops(const boost::mpl::int_<boost::multiprecision::number_kind_integer>&)
355 {
356    test_signed_integer_ops<Real>(boost::mpl::bool_<std::numeric_limits<Real>::is_signed>());
357 
358    Real a(20);
359    Real b(7);
360    Real c(5);
361    BOOST_CHECK_EQUAL(a % b ,  20 % 7);
362    BOOST_CHECK_EQUAL(a % 7 ,  20 % 7);
363    BOOST_CHECK_EQUAL(a % 7u ,  20 % 7);
364    BOOST_CHECK_EQUAL(a % a ,  0);
365    BOOST_CHECK_EQUAL(a % c ,  0);
366    BOOST_CHECK_EQUAL(a % 5 ,  0);
367    a = a % (b + 0);
368    BOOST_CHECK_EQUAL(a ,  20 % 7);
369    a = 20;
370    c = (a + 2) % (a - 1);
371    BOOST_CHECK_EQUAL(c ,  22 % 19);
372    c = 5;
373    a = b % (a - 15);
374    BOOST_CHECK_EQUAL(a ,  7 % 5);
375    a = 20;
376 
377    a = 20;
378    a %= 7;
379    BOOST_CHECK_EQUAL(a ,  20 % 7);
380 #ifndef BOOST_NO_LONG_LONG
381    a = 20;
382    a %= 7uLL;
383    BOOST_CHECK_EQUAL(a ,  20 % 7);
384 #endif
385    a = 20;
386    BOOST_CHECK_EQUAL(++a ,  21);
387    BOOST_CHECK_EQUAL(--a ,  20);
388    BOOST_CHECK_EQUAL(a++ ,  20);
389    BOOST_CHECK_EQUAL(a ,  21);
390    BOOST_CHECK_EQUAL(a-- ,  21);
391    BOOST_CHECK_EQUAL(a ,  20);
392    a = 2000;
393    a <<= 20;
394    BOOST_CHECK_EQUAL(a ,  2000L << 20);
395    a >>= 20;
396    BOOST_CHECK_EQUAL(a ,  2000);
397    a <<= 20u;
398    BOOST_CHECK_EQUAL(a ,  2000L << 20);
399    a >>= 20u;
400    BOOST_CHECK_EQUAL(a ,  2000);
401    BOOST_CHECK_THROW(a <<= -20, std::out_of_range);
402    BOOST_CHECK_THROW(a >>= -20, std::out_of_range);
403    BOOST_CHECK_THROW(Real(a << -20), std::out_of_range);
404    BOOST_CHECK_THROW(Real(a >> -20), std::out_of_range);
405 #ifndef BOOST_NO_LONG_LONG
406    if(sizeof(long long) > sizeof(std::size_t))
407    {
408       // extreme values should trigger an exception:
409       BOOST_CHECK_THROW(a >>= (1uLL << (sizeof(long long) * CHAR_BIT - 2)), std::out_of_range);
410       BOOST_CHECK_THROW(a <<= (1uLL << (sizeof(long long) * CHAR_BIT - 2)), std::out_of_range);
411       BOOST_CHECK_THROW(a >>= -(1LL << (sizeof(long long) * CHAR_BIT - 2)), std::out_of_range);
412       BOOST_CHECK_THROW(a <<= -(1LL << (sizeof(long long) * CHAR_BIT - 2)), std::out_of_range);
413       BOOST_CHECK_THROW(a >>= (1LL << (sizeof(long long) * CHAR_BIT - 2)), std::out_of_range);
414       BOOST_CHECK_THROW(a <<= (1LL << (sizeof(long long) * CHAR_BIT - 2)), std::out_of_range);
415       // Unless they fit within range:
416       a = 2000L;
417       BOOST_CHECK_EQUAL((a <<= 20uLL) ,  (2000L << 20));
418       a = 2000;
419       BOOST_CHECK_EQUAL((a <<= 20LL)  ,  (2000L << 20));
420 
421       BOOST_CHECK_THROW(Real(a >> (1uLL << (sizeof(long long) * CHAR_BIT - 2))), std::out_of_range);
422       BOOST_CHECK_THROW(Real(a <<= (1uLL << (sizeof(long long) * CHAR_BIT - 2))), std::out_of_range);
423       BOOST_CHECK_THROW(Real(a >>= -(1LL << (sizeof(long long) * CHAR_BIT - 2))), std::out_of_range);
424       BOOST_CHECK_THROW(Real(a <<= -(1LL << (sizeof(long long) * CHAR_BIT - 2))), std::out_of_range);
425       BOOST_CHECK_THROW(Real(a >>= (1LL << (sizeof(long long) * CHAR_BIT - 2))), std::out_of_range);
426       BOOST_CHECK_THROW(Real(a <<= (1LL << (sizeof(long long) * CHAR_BIT - 2))), std::out_of_range);
427       // Unless they fit within range:
428       a = 2000L;
429       BOOST_CHECK_EQUAL(Real(a << 20uLL) ,  (2000L << 20));
430       a = 2000;
431       BOOST_CHECK_EQUAL(Real(a << 20LL)  ,  (2000L << 20));
432    }
433 #endif
434    a = 20;
435    b = a << 20;
436    BOOST_CHECK_EQUAL(b ,  (20 << 20));
437    b = a >> 2;
438    BOOST_CHECK_EQUAL(b ,  (20 >> 2));
439    b = (a + 2) << 10;
440    BOOST_CHECK_EQUAL(b ,  (22 << 10));
441    b = (a + 3) >> 3;
442    BOOST_CHECK_EQUAL(b ,  (23 >> 3));
443    //
444    // Bit fiddling:
445    //
446    int i = 1020304;
447    int j = 56789123;
448    int k = 4523187;
449    a = i;
450    b = j;
451    c = a;
452    c &= b;
453    BOOST_CHECK_EQUAL(c ,  (i & j));
454    c = a;
455    c &= j;
456    BOOST_CHECK_EQUAL(c ,  (i & j));
457    c = a;
458    c &= a + b;
459    BOOST_CHECK_EQUAL(c ,  (i & (i + j)));
460    BOOST_CHECK_EQUAL((a & b) ,  (i & j));
461    c = k;
462    a = a & (b + k);
463    BOOST_CHECK_EQUAL(a ,  (i & (j + k)));
464    a = i;
465    a = (b + k) & a;
466    BOOST_CHECK_EQUAL(a ,  (i & (j + k)));
467    a = i;
468    c = a & b & k;
469    BOOST_CHECK_EQUAL(c ,  (i&j&k));
470    c = a;
471    c &= (c+b);
472    BOOST_CHECK_EQUAL(c ,  (i & (i+j)));
473    c = a & (b | 1);
474    BOOST_CHECK_EQUAL(c ,  (i & (j | 1)));
475 
476    test_complement<Real>(a, b, c, typename is_twos_complement_integer<Real>::type());
477 
478    a = i;
479    b = j;
480    c = a;
481    c |= b;
482    BOOST_CHECK_EQUAL(c ,  (i | j));
483    c = a;
484    c |= j;
485    BOOST_CHECK_EQUAL(c ,  (i | j));
486    c = a;
487    c |= a + b;
488    BOOST_CHECK_EQUAL(c ,  (i | (i + j)));
489    BOOST_CHECK_EQUAL((a | b) ,  (i | j));
490    c = k;
491    a = a | (b + k);
492    BOOST_CHECK_EQUAL(a ,  (i | (j + k)));
493    a = i;
494    a = (b + k) | a;
495    BOOST_CHECK_EQUAL(a ,  (i | (j + k)));
496    a = i;
497    c = a | b | k;
498    BOOST_CHECK_EQUAL(c ,  (i|j|k));
499    c = a;
500    c |= (c + b);
501    BOOST_CHECK_EQUAL(c ,  (i | (i+j)));
502    c = a | (b | 1);
503    BOOST_CHECK_EQUAL(c ,  (i | (j | 1)));
504 
505    a = i;
506    b = j;
507    c = a;
508    c ^= b;
509    BOOST_CHECK_EQUAL(c ,  (i ^ j));
510    c = a;
511    c ^= j;
512    BOOST_CHECK_EQUAL(c ,  (i ^ j));
513    c = a;
514    c ^= a + b;
515    BOOST_CHECK_EQUAL(c ,  (i ^ (i + j)));
516    BOOST_CHECK_EQUAL((a ^ b) ,  (i ^ j));
517    c = k;
518    a = a ^ (b + k);
519    BOOST_CHECK_EQUAL(a ,  (i ^ (j + k)));
520    a = i;
521    a = (b + k) ^ a;
522    BOOST_CHECK_EQUAL(a ,  (i ^ (j + k)));
523    a = i;
524    c = a ^ b ^ k;
525    BOOST_CHECK_EQUAL(c ,  (i^j^k));
526    c = a;
527    c ^= (c + b);
528    BOOST_CHECK_EQUAL(c ,  (i ^ (i+j)));
529    c = a ^ (b | 1);
530    BOOST_CHECK_EQUAL(c ,  (i ^ (j | 1)));
531 
532    a = i;
533    b = j;
534    c = k;
535    //
536    // Non-member functions:
537    //
538    a = 400;
539    b = 45;
540    BOOST_CHECK_EQUAL(gcd(a, b) ,  boost::math::gcd(400, 45));
541    BOOST_CHECK_EQUAL(lcm(a, b) ,  boost::math::lcm(400, 45));
542    BOOST_CHECK_EQUAL(gcd(a, 45) ,  boost::math::gcd(400, 45));
543    BOOST_CHECK_EQUAL(lcm(a, 45) ,  boost::math::lcm(400, 45));
544    BOOST_CHECK_EQUAL(gcd(a, 45u) ,  boost::math::gcd(400, 45));
545    BOOST_CHECK_EQUAL(lcm(a, 45u) ,  boost::math::lcm(400, 45));
546    BOOST_CHECK_EQUAL(gcd(400, b) ,  boost::math::gcd(400, 45));
547    BOOST_CHECK_EQUAL(lcm(400, b) ,  boost::math::lcm(400, 45));
548    BOOST_CHECK_EQUAL(gcd(400u, b) ,  boost::math::gcd(400, 45));
549    BOOST_CHECK_EQUAL(lcm(400u, b) ,  boost::math::lcm(400, 45));
550 
551    //
552    // Conditionals involving 2 arg functions:
553    //
554    test_conditional(Real(gcd(a, b)), gcd(a, b));
555 
556    Real r;
557    divide_qr(a, b, c, r);
558    BOOST_CHECK_EQUAL(c ,  a / b);
559    BOOST_CHECK_EQUAL(r ,  a % b);
560    divide_qr(a + 0, b, c, r);
561    BOOST_CHECK_EQUAL(c ,  a / b);
562    BOOST_CHECK_EQUAL(r ,  a % b);
563    divide_qr(a, b+0, c, r);
564    BOOST_CHECK_EQUAL(c ,  a / b);
565    BOOST_CHECK_EQUAL(r ,  a % b);
566    divide_qr(a+0, b+0, c, r);
567    BOOST_CHECK_EQUAL(c ,  a / b);
568    BOOST_CHECK_EQUAL(r ,  a % b);
569    BOOST_CHECK_EQUAL(integer_modulus(a, 57) ,  a % 57);
570    for(unsigned i = 0; i < 20; ++i)
571    {
572       if(std::numeric_limits<Real>::is_specialized && (!std::numeric_limits<Real>::is_bounded || ((int)i * 17 < std::numeric_limits<Real>::digits)))
573       {
574          BOOST_CHECK_EQUAL(lsb(Real(1) << (i * 17)) ,  i * 17);
575          BOOST_CHECK_EQUAL(msb(Real(1) << (i * 17)) ,  i * 17);
576          BOOST_CHECK(bit_test(Real(1) << (i * 17), i * 17));
577          BOOST_CHECK(!bit_test(Real(1) << (i * 17), i * 17 + 1));
578          if(i)
579          {
580             BOOST_CHECK(!bit_test(Real(1) << (i * 17), i * 17 - 1));
581          }
582          Real zero(0);
583          BOOST_CHECK(bit_test(bit_set(zero, i * 17), i * 17));
584          zero = 0;
585          BOOST_CHECK_EQUAL(bit_flip(zero, i*17) ,  Real(1) << i * 17);
586          zero = Real(1) << i * 17;
587          BOOST_CHECK_EQUAL(bit_flip(zero, i * 17) ,  0);
588          zero = Real(1) << i * 17;
589          BOOST_CHECK_EQUAL(bit_unset(zero, i * 17) ,  0);
590       }
591    }
592    //
593    // pow, powm:
594    //
595    BOOST_CHECK_EQUAL(pow(Real(3), 4) ,  81);
596    BOOST_CHECK_EQUAL(pow(Real(3) + Real(0), 4) ,  81);
597    BOOST_CHECK_EQUAL(powm(Real(3), Real(4), Real(13)) ,  81 % 13);
598    BOOST_CHECK_EQUAL(powm(Real(3), Real(4), 13) ,  81 % 13);
599    BOOST_CHECK_EQUAL(powm(Real(3), Real(4), Real(13) + 0) ,  81 % 13);
600    BOOST_CHECK_EQUAL(powm(Real(3), Real(4) + 0, Real(13)) ,  81 % 13);
601    BOOST_CHECK_EQUAL(powm(Real(3), Real(4) + 0, 13) ,  81 % 13);
602    BOOST_CHECK_EQUAL(powm(Real(3), Real(4) + 0, Real(13) + 0) ,  81 % 13);
603    BOOST_CHECK_EQUAL(powm(Real(3), 4 + 0, Real(13)) ,  81 % 13);
604    BOOST_CHECK_EQUAL(powm(Real(3), 4 + 0, 13) ,  81 % 13);
605    BOOST_CHECK_EQUAL(powm(Real(3), 4 + 0, Real(13) + 0) ,  81 % 13);
606    BOOST_CHECK_EQUAL(powm(Real(3) + 0, Real(4), Real(13)) ,  81 % 13);
607    BOOST_CHECK_EQUAL(powm(Real(3) + 0, Real(4), 13) ,  81 % 13);
608    BOOST_CHECK_EQUAL(powm(Real(3) + 0, Real(4), Real(13) + 0) ,  81 % 13);
609    BOOST_CHECK_EQUAL(powm(Real(3) + 0, Real(4) + 0, Real(13)) ,  81 % 13);
610    BOOST_CHECK_EQUAL(powm(Real(3) + 0, Real(4) + 0, 13) ,  81 % 13);
611    BOOST_CHECK_EQUAL(powm(Real(3) + 0, Real(4) + 0, Real(13) + 0) ,  81 % 13);
612    BOOST_CHECK_EQUAL(powm(Real(3) + 0, 4 + 0, Real(13)) ,  81 % 13);
613    BOOST_CHECK_EQUAL(powm(Real(3) + 0, 4 + 0, 13) ,  81 % 13);
614    BOOST_CHECK_EQUAL(powm(Real(3) + 0, 4 + 0, Real(13) + 0) ,  81 % 13);
615    //
616    // Conditionals involving 3 arg functions:
617    //
618    test_conditional(Real(powm(Real(3), Real(4), Real(13))), powm(Real(3), Real(4), Real(13)));
619 
620    //
621    // Things that are expected errors:
622    //
623    BOOST_CHECK_THROW(Real("3.14"), std::runtime_error);
624    BOOST_CHECK_THROW(Real("3L"), std::runtime_error);
625    BOOST_CHECK_THROW(Real(Real(20) / 0u), std::overflow_error);
626    //
627    // Extra tests added for full coverage:
628    //
629    a = 20;
630    b = 7;
631    c = 20 % b;
632    BOOST_CHECK_EQUAL(c ,  (20 % 7));
633    c = 20 % (b + 0);
634    BOOST_CHECK_EQUAL(c ,  (20 % 7));
635    c = a & 10;
636    BOOST_CHECK_EQUAL(c ,  (20 & 10));
637    c = 10 & a;
638    BOOST_CHECK_EQUAL(c ,  (20 & 10));
639    c = (a + 0) & (b + 0);
640    BOOST_CHECK_EQUAL(c ,  (20 & 7));
641    c = 10 & (a + 0);
642    BOOST_CHECK_EQUAL(c ,  (20 & 10));
643    c = 10 | a;
644    BOOST_CHECK_EQUAL(c ,  (20 | 10));
645    c = (a + 0) | (b + 0);
646    BOOST_CHECK(c == (20 | 7))
647    c = 20 | (b + 0);
648    BOOST_CHECK_EQUAL(c ,  (20 | 7));
649    c = a ^ 7;
650    BOOST_CHECK_EQUAL(c ,  (20 ^ 7));
651    c = 20 ^ b;
652    BOOST_CHECK_EQUAL(c ,  (20 ^ 7));
653    c = (a + 0) ^ (b + 0);
654    BOOST_CHECK_EQUAL(c ,  (20 ^ 7));
655    c = 20 ^ (b + 0);
656    BOOST_CHECK_EQUAL(c ,  (20 ^ 7));
657 }
658 
659 template <class Real, class T>
test_float_funcs(const T &)660 void test_float_funcs(const T&){}
661 
662 template <class Real>
test_float_funcs(const boost::mpl::true_ &)663 void test_float_funcs(const boost::mpl::true_&)
664 {
665    if(boost::multiprecision::is_interval_number<Real>::value)
666       return;
667    //
668    // Test variable reuse in function calls, see https://svn.boost.org/trac/boost/ticket/8326
669    //
670    Real a(2), b(10);
671    a = pow(a, b);
672    BOOST_CHECK_EQUAL(a, 1024);
673    a = 2;
674    b = pow(a, b);
675    BOOST_CHECK_EQUAL(b, 1024);
676    b = 10;
677    a = pow(a, 10);
678    BOOST_CHECK_EQUAL(a, 1024);
679    a = -2;
680    a = abs(a);
681    BOOST_CHECK_EQUAL(a, 2);
682    a = -2;
683    a = fabs(a);
684    BOOST_CHECK_EQUAL(a, 2);
685    a = 2.5;
686    a = floor(a);
687    BOOST_CHECK_EQUAL(a, 2);
688    a = 2.5;
689    a = ceil(a);
690    BOOST_CHECK_EQUAL(a, 3);
691    a = 2.5;
692    a = trunc(a);
693    BOOST_CHECK_EQUAL(a, 2);
694    a = 2.25;
695    a = round(a);
696    BOOST_CHECK_EQUAL(a, 2);
697    a = 2;
698    a = ldexp(a, 1);
699    BOOST_CHECK_EQUAL(a, 4);
700    int i;
701    a = frexp(a, &i);
702    BOOST_CHECK_EQUAL(a, 0.5);
703 
704    Real tol = std::numeric_limits<Real>::epsilon() * 3;
705    a = 4;
706    a = sqrt(a);
707    BOOST_CHECK_CLOSE_FRACTION(a, 2, tol);
708    a = 3;
709    a = exp(a);
710    BOOST_CHECK_CLOSE_FRACTION(a, Real(exp(Real(3))), tol);
711    a = 3;
712    a = log(a);
713    BOOST_CHECK_CLOSE_FRACTION(a, Real(log(Real(3))), tol);
714    a = 3;
715    a = log10(a);
716    BOOST_CHECK_CLOSE_FRACTION(a, Real(log10(Real(3))), tol);
717 
718    a = 0.5;
719    a = sin(a);
720    BOOST_CHECK_CLOSE_FRACTION(a, Real(sin(Real(0.5))), tol);
721    a = 0.5;
722    a = cos(a);
723    BOOST_CHECK_CLOSE_FRACTION(a, Real(cos(Real(0.5))), tol);
724    a = 0.5;
725    a = tan(a);
726    BOOST_CHECK_CLOSE_FRACTION(a, Real(tan(Real(0.5))), tol);
727    a = 0.5;
728    a = asin(a);
729    BOOST_CHECK_CLOSE_FRACTION(a, Real(asin(Real(0.5))), tol);
730    a = 0.5;
731    a = acos(a);
732    BOOST_CHECK_CLOSE_FRACTION(a, Real(acos(Real(0.5))), tol);
733    a = 0.5;
734    a = atan(a);
735    BOOST_CHECK_CLOSE_FRACTION(a, Real(atan(Real(0.5))), tol);
736    a = 0.5;
737    a = sinh(a);
738    BOOST_CHECK_CLOSE_FRACTION(a, Real(sinh(Real(0.5))), tol);
739    a = 0.5;
740    a = cosh(a);
741    BOOST_CHECK_CLOSE_FRACTION(a, Real(cosh(Real(0.5))), tol);
742    a = 0.5;
743    a = tanh(a);
744    BOOST_CHECK_CLOSE_FRACTION(a, Real(tanh(Real(0.5))), tol);
745    a = 4;
746    b = 2;
747    a = fmod(a, b);
748    BOOST_CHECK_CLOSE_FRACTION(a, Real(fmod(Real(4), Real(2))), tol);
749    a = 4;
750    b = fmod(a, b);
751    BOOST_CHECK_CLOSE_FRACTION(b, Real(fmod(Real(4), Real(2))), tol);
752    b = 2;
753    a = atan2(a, b);
754    BOOST_CHECK_CLOSE_FRACTION(a, Real(atan2(Real(4), Real(2))), tol);
755    a = 4;
756    b = atan2(a, b);
757    BOOST_CHECK_CLOSE_FRACTION(b, Real(atan2(Real(4), Real(2))), tol);
758 }
759 
760 template <class T, class U>
compare_NaNs(const T & a,const U & b)761 void compare_NaNs(const T& a, const U& b)
762 {
763    BOOST_CHECK_EQUAL(a == b, false);
764    BOOST_CHECK_EQUAL(a != b, true);
765    BOOST_CHECK_EQUAL(a <= b, false);
766    BOOST_CHECK_EQUAL(a >= b, false);
767    BOOST_CHECK_EQUAL(a > b, false);
768    BOOST_CHECK_EQUAL(a < b, false);
769    //
770    // Again where LHS may be an expression template:
771    //
772    BOOST_CHECK_EQUAL(1 * a == b, false);
773    BOOST_CHECK_EQUAL(1 * a != b, true);
774    BOOST_CHECK_EQUAL(1 * a <= b, false);
775    BOOST_CHECK_EQUAL(1 * a >= b, false);
776    BOOST_CHECK_EQUAL(1 * a > b, false);
777    BOOST_CHECK_EQUAL(1 * a < b, false);
778    //
779    // Again where RHS may be an expression template:
780    //
781    BOOST_CHECK_EQUAL(a == b * 1, false);
782    BOOST_CHECK_EQUAL(a != b * 1, true);
783    BOOST_CHECK_EQUAL(a <= b * 1, false);
784    BOOST_CHECK_EQUAL(a >= b * 1, false);
785    BOOST_CHECK_EQUAL(a > b * 1, false);
786    BOOST_CHECK_EQUAL(a < b * 1, false);
787    //
788    // Again where LHS and RHS may be an expression templates:
789    //
790    BOOST_CHECK_EQUAL(1 * a == b * 1, false);
791    BOOST_CHECK_EQUAL(1 * a != b * 1, true);
792    BOOST_CHECK_EQUAL(1 * a <= b * 1, false);
793    BOOST_CHECK_EQUAL(1 * a >= b * 1, false);
794    BOOST_CHECK_EQUAL(1 * a > b * 1, false);
795    BOOST_CHECK_EQUAL(1 * a < b * 1, false);
796 }
797 
798 template <class Real, class T>
test_float_ops(const T &)799 void test_float_ops(const T&){}
800 
801 template <class Real>
test_float_ops(const boost::mpl::int_<boost::multiprecision::number_kind_floating_point> &)802 void test_float_ops(const boost::mpl::int_<boost::multiprecision::number_kind_floating_point>&)
803 {
804    BOOST_CHECK_EQUAL(abs(Real(2)) ,  2);
805    BOOST_CHECK_EQUAL(abs(Real(-2)) ,  2);
806    BOOST_CHECK_EQUAL(fabs(Real(2)) ,  2);
807    BOOST_CHECK_EQUAL(fabs(Real(-2)) ,  2);
808    BOOST_CHECK_EQUAL(floor(Real(5) / 2) ,  2);
809    BOOST_CHECK_EQUAL(ceil(Real(5) / 2) ,  3);
810    BOOST_CHECK_EQUAL(floor(Real(-5) / 2) ,  -3);
811    BOOST_CHECK_EQUAL(ceil(Real(-5) / 2) ,  -2);
812    BOOST_CHECK_EQUAL(trunc(Real(5) / 2) ,  2);
813    BOOST_CHECK_EQUAL(trunc(Real(-5) / 2) ,  -2);
814    //
815    // ldexp and frexp, these pretty much have to be implemented by each backend:
816    //
817    BOOST_CHECK_EQUAL(ldexp(Real(2), 5) ,  64);
818    BOOST_CHECK_EQUAL(ldexp(Real(2), -5) ,  Real(2) / 32);
819    Real v(512);
820    int exponent;
821    Real r = frexp(v, &exponent);
822    BOOST_CHECK_EQUAL(r ,  0.5);
823    BOOST_CHECK_EQUAL(exponent ,  10);
824    BOOST_CHECK_EQUAL(v ,  512);
825    v = 1 / v;
826    r = frexp(v, &exponent);
827    BOOST_CHECK_EQUAL(r ,  0.5);
828    BOOST_CHECK_EQUAL(exponent ,  -8);
829    typedef typename Real::backend_type::exponent_type e_type;
830    BOOST_CHECK_EQUAL(ldexp(Real(2), e_type(5)) ,  64);
831    BOOST_CHECK_EQUAL(ldexp(Real(2), e_type(-5)) ,  Real(2) / 32);
832    v = 512;
833    e_type exp2;
834    r = frexp(v, &exp2);
835    BOOST_CHECK_EQUAL(r ,  0.5);
836    BOOST_CHECK_EQUAL(exp2 ,  10);
837    BOOST_CHECK_EQUAL(v ,  512);
838    v = 1 / v;
839    r = frexp(v, &exp2);
840    BOOST_CHECK_EQUAL(r ,  0.5);
841    BOOST_CHECK_EQUAL(exp2 ,  -8);
842    //
843    // scalbn and logb, these are the same as ldexp and frexp unless the radix is
844    // something other than 2:
845    //
846    if(std::numeric_limits<Real>::is_specialized && std::numeric_limits<Real>::radix)
847    {
848       BOOST_CHECK_EQUAL(scalbn(Real(2), 5), 2 * pow(double(std::numeric_limits<Real>::radix), 5));
849       BOOST_CHECK_EQUAL(scalbn(Real(2), -5), Real(2) / pow(double(std::numeric_limits<Real>::radix), 5));
850       Real v(512);
851       int exponent;
852       Real r;
853       exponent = ilogb(v);
854       r = scalbn(v, -exponent);
855       BOOST_CHECK(r >= 1);
856       BOOST_CHECK(r < std::numeric_limits<Real>::radix);
857       BOOST_CHECK_EQUAL(exponent, logb(v));
858       BOOST_CHECK_EQUAL(v, scalbn(r, exponent));
859       v = 1 / v;
860       exponent = ilogb(v);
861       r = scalbn(v, -exponent);
862       BOOST_CHECK(r >= 1);
863       BOOST_CHECK(r < std::numeric_limits<Real>::radix);
864       BOOST_CHECK_EQUAL(exponent, logb(v));
865       BOOST_CHECK_EQUAL(v, scalbn(r, exponent));
866    }
867    //
868    // pow and exponent:
869    //
870    v = 3.25;
871    r = pow(v, 0);
872    BOOST_CHECK_EQUAL(r ,  1);
873    r = pow(v, 1);
874    BOOST_CHECK_EQUAL(r ,  3.25);
875    r = pow(v, 2);
876    BOOST_CHECK_EQUAL(r ,  boost::math::pow<2>(3.25));
877    r = pow(v, 3);
878    BOOST_CHECK_EQUAL(r ,  boost::math::pow<3>(3.25));
879    r = pow(v, 4);
880    BOOST_CHECK_EQUAL(r ,  boost::math::pow<4>(3.25));
881    r = pow(v, 5);
882    BOOST_CHECK_EQUAL(r ,  boost::math::pow<5>(3.25));
883    r = pow(v, 6);
884    BOOST_CHECK_EQUAL(r ,  boost::math::pow<6>(3.25));
885    r = pow(v, 25);
886    BOOST_CHECK_EQUAL(r ,  boost::math::pow<25>(Real(3.25)));
887    //
888    // Things that are expected errors:
889    //
890    BOOST_CHECK_THROW(Real("3.14L"), std::runtime_error);
891    if(std::numeric_limits<Real>::is_specialized)
892    {
893       if(std::numeric_limits<Real>::has_infinity)
894       {
895          BOOST_CHECK((boost::math::isinf)(Real(20) / 0u));
896       }
897       else
898       {
899          BOOST_CHECK_THROW(Real(Real(20) / 0u), std::overflow_error);
900       }
901    }
902    //
903    // Comparisons of NaN's should always fail:
904    //
905    if(std::numeric_limits<Real>::has_quiet_NaN)
906    {
907       r = v = std::numeric_limits<Real>::quiet_NaN();
908       compare_NaNs(r, v);
909       v = 0;
910       compare_NaNs(r, v);
911       r.swap(v);
912       compare_NaNs(r, v);
913       //
914       // Conmpare NaN to int:
915       //
916       compare_NaNs(v, 0);
917       compare_NaNs(0, v);
918       //
919       // Compare to floats:
920       //
921       compare_NaNs(v, 0.5);
922       compare_NaNs(0.5, v);
923       if(std::numeric_limits<double>::has_quiet_NaN)
924       {
925          compare_NaNs(r, std::numeric_limits<double>::quiet_NaN());
926          compare_NaNs(std::numeric_limits<double>::quiet_NaN(), r);
927       }
928    }
929 
930    test_float_funcs<Real>(boost::mpl::bool_<std::numeric_limits<Real>::is_specialized>());
931 }
932 
933 template <class T>
934 struct lexical_cast_target_type
935 {
936    typedef typename boost::mpl::if_<
937       boost::is_signed<T>,
938       boost::intmax_t,
939       typename boost::mpl::if_<
940          boost::is_unsigned<T>,
941          boost::uintmax_t,
942          T
943       >::type
944    >::type type;
945 };
946 
947 template <class Real, class Num>
test_negative_mixed_minmax(boost::mpl::true_ const &)948 void test_negative_mixed_minmax(boost::mpl::true_ const&)
949 {
950    if(!std::numeric_limits<Real>::is_bounded || (std::numeric_limits<Real>::digits >= std::numeric_limits<Num>::digits))
951    {
952       Real mx1((std::numeric_limits<Num>::max)() - 1);
953       ++mx1;
954       Real mx2((std::numeric_limits<Num>::max)());
955       BOOST_CHECK_EQUAL(mx1, mx2);
956       mx1 = (std::numeric_limits<Num>::max)() - 1;
957       ++mx1;
958       mx2 = (std::numeric_limits<Num>::max)();
959       BOOST_CHECK_EQUAL(mx1, mx2);
960 
961       if(!std::numeric_limits<Real>::is_bounded || (std::numeric_limits<Real>::digits > std::numeric_limits<Num>::digits))
962       {
963          Real mx3((std::numeric_limits<Num>::min)() + 1);
964          --mx3;
965          Real mx4((std::numeric_limits<Num>::min)());
966          BOOST_CHECK_EQUAL(mx3, mx4);
967          mx3 = (std::numeric_limits<Num>::min)() + 1;
968          --mx3;
969          mx4 = (std::numeric_limits<Num>::min)();
970          BOOST_CHECK_EQUAL(mx3, mx4);
971       }
972    }
973 }
974 template <class Real, class Num>
test_negative_mixed_minmax(boost::mpl::false_ const &)975 void test_negative_mixed_minmax(boost::mpl::false_ const&)
976 {
977 }
978 
979 template <class Real, class Num>
test_negative_mixed(boost::mpl::true_ const &)980 void test_negative_mixed(boost::mpl::true_ const&)
981 {
982    typedef typename lexical_cast_target_type<Num>::type target_type;
983    typedef typename boost::mpl::if_<
984          boost::is_convertible<Num, Real>,
985          typename boost::mpl::if_c<boost::is_integral<Num>::value && (sizeof(Num) < sizeof(int)), int, Num>::type,
986          Real
987       >::type cast_type;
988    typedef typename boost::mpl::if_<
989          boost::is_convertible<Num, Real>,
990          Num,
991          Real
992       >::type simple_cast_type;
993    std::cout << "Testing mixed arithmetic with type: " << typeid(Real).name()  << " and " << typeid(Num).name() << std::endl;
994    static const int left_shift = std::numeric_limits<Num>::digits - 1;
995    Num n1 = -static_cast<Num>(1uLL << ((left_shift < 63) && (left_shift > 0) ? left_shift : 10));
996    Num n2 = -1;
997    Num n3 = 0;
998    Num n4 = -20;
999    Num n5 = -8;
1000 
1001    test_comparisons<Real>(n1, n2, boost::is_convertible<Num, Real>());
1002    test_comparisons<Real>(n1, n3, boost::is_convertible<Num, Real>());
1003    test_comparisons<Real>(n3, n1, boost::is_convertible<Num, Real>());
1004    test_comparisons<Real>(n2, n1, boost::is_convertible<Num, Real>());
1005    test_comparisons<Real>(n1, n1, boost::is_convertible<Num, Real>());
1006    test_comparisons<Real>(n3, n3, boost::is_convertible<Num, Real>());
1007 
1008    // Default construct:
1009    BOOST_CHECK_EQUAL(Real(n1) ,  static_cast<cast_type>(n1));
1010    BOOST_CHECK_EQUAL(Real(n2) ,  static_cast<cast_type>(n2));
1011    BOOST_CHECK_EQUAL(Real(n3) ,  static_cast<cast_type>(n3));
1012    BOOST_CHECK_EQUAL(Real(n4) ,  static_cast<cast_type>(n4));
1013    BOOST_CHECK_EQUAL(static_cast<cast_type>(n1) ,  Real(n1));
1014    BOOST_CHECK_EQUAL(static_cast<cast_type>(n2) ,  Real(n2));
1015    BOOST_CHECK_EQUAL(static_cast<cast_type>(n3) ,  Real(n3));
1016    BOOST_CHECK_EQUAL(static_cast<cast_type>(n4) ,  Real(n4));
1017    BOOST_CHECK_EQUAL(Real(n1).template convert_to<Num>() ,  n1);
1018    BOOST_CHECK_EQUAL(Real(n2).template convert_to<Num>() ,  n2);
1019    BOOST_CHECK_EQUAL(Real(n3).template convert_to<Num>() ,  n3);
1020    BOOST_CHECK_EQUAL(Real(n4).template convert_to<Num>() ,  n4);
1021 #ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
1022    BOOST_CHECK_EQUAL(static_cast<Num>(Real(n1)) ,  n1);
1023    BOOST_CHECK_EQUAL(static_cast<Num>(Real(n2)) ,  n2);
1024    BOOST_CHECK_EQUAL(static_cast<Num>(Real(n3)) ,  n3);
1025    BOOST_CHECK_EQUAL(static_cast<Num>(Real(n4)) ,  n4);
1026 #endif
1027 #if defined(TEST_MPFR)
1028    Num tol = 10 * std::numeric_limits<Num>::epsilon();
1029 #else
1030    Num tol = 0;
1031 #endif
1032    std::ios_base::fmtflags f = boost::is_floating_point<Num>::value ? std::ios_base::scientific : std::ios_base::fmtflags(0);
1033    int digits_to_print = boost::is_floating_point<Num>::value && std::numeric_limits<Num>::is_specialized
1034       ? std::numeric_limits<Num>::digits10 + 5 : 0;
1035    if(std::numeric_limits<target_type>::digits <= std::numeric_limits<Real>::digits)
1036    {
1037       BOOST_CHECK_CLOSE(n1, checked_lexical_cast<target_type>(Real(n1).str(digits_to_print, f)), tol);
1038    }
1039    BOOST_CHECK_CLOSE(n2, checked_lexical_cast<target_type>(Real(n2).str(digits_to_print, f)), 0);
1040    BOOST_CHECK_CLOSE(n3, checked_lexical_cast<target_type>(Real(n3).str(digits_to_print, f)), 0);
1041    BOOST_CHECK_CLOSE(n4, checked_lexical_cast<target_type>(Real(n4).str(digits_to_print, f)), 0);
1042    // Assignment:
1043    Real r(0);
1044    BOOST_CHECK(r != static_cast<cast_type>(n1));
1045    r = static_cast<simple_cast_type>(n1);
1046    BOOST_CHECK_EQUAL(r ,  static_cast<cast_type>(n1));
1047    r = static_cast<simple_cast_type>(n2);
1048    BOOST_CHECK_EQUAL(r ,  static_cast<cast_type>(n2));
1049    r = static_cast<simple_cast_type>(n3);
1050    BOOST_CHECK_EQUAL(r ,  static_cast<cast_type>(n3));
1051    r = static_cast<simple_cast_type>(n4);
1052    BOOST_CHECK_EQUAL(r ,  static_cast<cast_type>(n4));
1053    // Addition:
1054    r = static_cast<simple_cast_type>(n2);
1055    BOOST_CHECK_EQUAL(r + static_cast<simple_cast_type>(n4) ,  static_cast<cast_type>(n2 + n4));
1056    BOOST_CHECK_EQUAL(Real(r + static_cast<simple_cast_type>(n4)) ,  static_cast<cast_type>(n2 + n4));
1057    r += static_cast<simple_cast_type>(n4);
1058    BOOST_CHECK_EQUAL(r ,  static_cast<cast_type>(n2 + n4));
1059    // subtraction:
1060    r = static_cast<simple_cast_type>(n4);
1061    BOOST_CHECK_EQUAL(r - static_cast<simple_cast_type>(n5) ,  static_cast<cast_type>(n4 - n5));
1062    BOOST_CHECK_EQUAL(Real(r - static_cast<simple_cast_type>(n5)) ,  static_cast<cast_type>(n4 - n5));
1063    r -= static_cast<simple_cast_type>(n5);
1064    BOOST_CHECK_EQUAL(r ,  static_cast<cast_type>(n4 - n5));
1065    // Multiplication:
1066    r = static_cast<simple_cast_type>(n2);
1067    BOOST_CHECK_EQUAL(r * static_cast<simple_cast_type>(n4) ,  static_cast<cast_type>(n2 * n4));
1068    BOOST_CHECK_EQUAL(Real(r * static_cast<simple_cast_type>(n4)) ,  static_cast<cast_type>(n2 * n4));
1069    r *= static_cast<simple_cast_type>(n4);
1070    BOOST_CHECK_EQUAL(r ,  static_cast<cast_type>(n2 * n4));
1071    // Division:
1072    r = static_cast<simple_cast_type>(n1);
1073    BOOST_CHECK_EQUAL(r / static_cast<simple_cast_type>(n5) ,  static_cast<cast_type>(n1 / n5));
1074    BOOST_CHECK_EQUAL(Real(r / static_cast<simple_cast_type>(n5)) ,  static_cast<cast_type>(n1 / n5));
1075    r /= static_cast<simple_cast_type>(n5);
1076    BOOST_CHECK_EQUAL(r ,  static_cast<cast_type>(n1 / n5));
1077    //
1078    // Extra cases for full coverage:
1079    //
1080    r = Real(n4) + static_cast<simple_cast_type>(n5);
1081    BOOST_CHECK_EQUAL(r ,  static_cast<cast_type>(n4 + n5));
1082    r = static_cast<simple_cast_type>(n4) + Real(n5);
1083    BOOST_CHECK_EQUAL(r ,  static_cast<cast_type>(n4 + n5));
1084    r = Real(n4) - static_cast<simple_cast_type>(n5);
1085    BOOST_CHECK_EQUAL(r ,  static_cast<cast_type>(n4 - n5));
1086    r = static_cast<simple_cast_type>(n4) - Real(n5);
1087    BOOST_CHECK_EQUAL(r ,  static_cast<cast_type>(n4 - n5));
1088    r = static_cast<simple_cast_type>(n4) * Real(n5);
1089    BOOST_CHECK_EQUAL(r ,  static_cast<cast_type>(n4 * n5));
1090    r = static_cast<cast_type>(4 * n4) / Real(4);
1091    BOOST_CHECK_EQUAL(r ,  static_cast<cast_type>(n4));
1092 
1093    Real a, b, c;
1094    a = 20;
1095    b = 30;
1096    c = -a + b;
1097    BOOST_CHECK_EQUAL(c ,  10);
1098    c = b + -a;
1099    BOOST_CHECK_EQUAL(c ,  10);
1100    n4 = 30;
1101    c = -a + static_cast<cast_type>(n4);
1102    BOOST_CHECK_EQUAL(c ,  10);
1103    c = static_cast<cast_type>(n4) + -a;
1104    BOOST_CHECK_EQUAL(c ,  10);
1105    c = -a + -b;
1106    BOOST_CHECK_EQUAL(c ,  -50);
1107    n4 = 4;
1108    c = -(a + b) + static_cast<cast_type>(n4);
1109    BOOST_CHECK_EQUAL(c ,  -50+4);
1110    n4 = 50;
1111    c = (a + b) - static_cast<cast_type>(n4);
1112    BOOST_CHECK_EQUAL(c ,  0);
1113    c = (a + b) - static_cast<cast_type>(n4);
1114    BOOST_CHECK_EQUAL(c ,  0);
1115    c = a - -(b + static_cast<cast_type>(n4));
1116    BOOST_CHECK_EQUAL(c ,  20 - -(30 + 50));
1117    c = -(b + static_cast<cast_type>(n4)) - a;
1118    BOOST_CHECK_EQUAL(c ,  -(30 + 50) - 20);
1119    c = a - -b;
1120    BOOST_CHECK_EQUAL(c ,  50);
1121    c = -a - b;
1122    BOOST_CHECK_EQUAL(c ,  -50);
1123    c = -a - static_cast<cast_type>(n4);
1124    BOOST_CHECK_EQUAL(c ,  -20 - 50);
1125    c = static_cast<cast_type>(n4) - -a;
1126    BOOST_CHECK_EQUAL(c ,  50 + 20);
1127    c = -(a + b) - Real(n4);
1128    BOOST_CHECK_EQUAL(c ,  -(20 + 30) - 50);
1129    c = static_cast<cast_type>(n4) - (a + b);
1130    BOOST_CHECK_EQUAL(c ,  0);
1131    c = (a + b) * static_cast<cast_type>(n4);
1132    BOOST_CHECK_EQUAL(c ,  50 * 50);
1133    c = static_cast<cast_type>(n4) * (a + b);
1134    BOOST_CHECK_EQUAL(c ,  50 * 50);
1135    c = a * -(b + static_cast<cast_type>(n4));
1136    BOOST_CHECK_EQUAL(c ,  20 * -(30 + 50));
1137    c = -(b + static_cast<cast_type>(n4)) * a;
1138    BOOST_CHECK_EQUAL(c ,  20 * -(30 + 50));
1139    c = a * -b;
1140    BOOST_CHECK_EQUAL(c ,  20 * -30);
1141    c = -a * b;
1142    BOOST_CHECK_EQUAL(c ,  20 * -30);
1143    c = -a * static_cast<cast_type>(n4);
1144    BOOST_CHECK_EQUAL(c ,  -20 * 50);
1145    c = static_cast<cast_type>(n4) * -a;
1146    BOOST_CHECK_EQUAL(c ,  -20 * 50);
1147    c = -(a + b) + a;
1148    BOOST_CHECK(-50 + 20);
1149    c = static_cast<cast_type>(n4) - (a + b);
1150    BOOST_CHECK_EQUAL(c ,  0);
1151    Real d = 10;
1152    c = (a + b) / d;
1153    BOOST_CHECK_EQUAL(c ,  5);
1154    c = (a + b) / (d + 0);
1155    BOOST_CHECK_EQUAL(c ,  5);
1156    c = (a + b) / static_cast<cast_type>(n4);
1157    BOOST_CHECK_EQUAL(c ,  1);
1158    c = static_cast<cast_type>(n4) / (a + b);
1159    BOOST_CHECK_EQUAL(c ,  1);
1160    d = 50;
1161    c = d / -(a + b);
1162    BOOST_CHECK_EQUAL(c ,  -1);
1163    c = -(a + b) / d;
1164    BOOST_CHECK_EQUAL(c ,  -1);
1165    d = 2;
1166    c = a / -d;
1167    BOOST_CHECK_EQUAL(c ,  20 / -2);
1168    c = -a / d;
1169    BOOST_CHECK_EQUAL(c ,  20 / -2);
1170    d = 50;
1171    c = -d / static_cast<cast_type>(n4);
1172    BOOST_CHECK_EQUAL(c ,  -1);
1173    c = static_cast<cast_type>(n4) / -d;
1174    BOOST_CHECK_EQUAL(c ,  -1);
1175    c = static_cast<cast_type>(n4) + a;
1176    BOOST_CHECK_EQUAL(c ,  70);
1177    c = static_cast<cast_type>(n4) - a;
1178    BOOST_CHECK_EQUAL(c ,  30);
1179    c = static_cast<cast_type>(n4) * a;
1180    BOOST_CHECK_EQUAL(c ,  50 * 20);
1181 
1182    n1 = -2;
1183    n2 = -3;
1184    n3 = -4;
1185    a = static_cast<cast_type>(n1);
1186    b = static_cast<cast_type>(n2);
1187    c = static_cast<cast_type>(n3);
1188    d = a + b * c;
1189    BOOST_CHECK_EQUAL(d ,  -2 + -3 * -4);
1190    d = static_cast<cast_type>(n1) + b * c;
1191    BOOST_CHECK_EQUAL(d ,  -2 + -3 * -4);
1192    d = a + static_cast<cast_type>(n2) * c;
1193    BOOST_CHECK_EQUAL(d ,  -2 + -3 * -4);
1194    d = a + b * static_cast<cast_type>(n3);
1195    BOOST_CHECK_EQUAL(d ,  -2 + -3 * -4);
1196    d = static_cast<cast_type>(n1) + static_cast<cast_type>(n2) * c;
1197    BOOST_CHECK_EQUAL(d ,  -2 + -3 * -4);
1198    d = static_cast<cast_type>(n1) + b * static_cast<cast_type>(n3);
1199    BOOST_CHECK_EQUAL(d ,  -2 + -3 * -4);
1200    a += static_cast<cast_type>(n2) * c;
1201    BOOST_CHECK_EQUAL(a ,  -2 + -3 * -4);
1202    a = static_cast<cast_type>(n1);
1203    a += b * static_cast<cast_type>(n3);
1204    BOOST_CHECK_EQUAL(a ,  -2 + -3 * -4);
1205    a = static_cast<cast_type>(n1);
1206 
1207    d = b * c + a;
1208    BOOST_CHECK_EQUAL(d ,  -2 + -3 * -4);
1209    d = b * c + static_cast<cast_type>(n1);
1210    BOOST_CHECK_EQUAL(d ,  -2 + -3 * -4);
1211    d = static_cast<cast_type>(n2) * c + a;
1212    BOOST_CHECK_EQUAL(d ,  -2 + -3 * -4);
1213    d = b * static_cast<cast_type>(n3) + a;
1214    BOOST_CHECK_EQUAL(d ,  -2 + -3 * -4);
1215    d = static_cast<cast_type>(n2) * c + static_cast<cast_type>(n1);
1216    BOOST_CHECK_EQUAL(d ,  -2 + -3 * -4);
1217    d = b * static_cast<cast_type>(n3) + static_cast<cast_type>(n1);
1218    BOOST_CHECK_EQUAL(d ,  -2 + -3 * -4);
1219 
1220    a = -20;
1221    d = a - b * c;
1222    BOOST_CHECK_EQUAL(d ,  -20 - -3 * -4);
1223    n1 = -20;
1224    d = static_cast<cast_type>(n1) - b * c;
1225    BOOST_CHECK_EQUAL(d ,  -20 - -3 * -4);
1226    d = a - static_cast<cast_type>(n2) * c;
1227    BOOST_CHECK_EQUAL(d ,  -20 - -3 * -4);
1228    d = a - b * static_cast<cast_type>(n3);
1229    BOOST_CHECK_EQUAL(d ,  -20 - -3 * -4);
1230    d = static_cast<cast_type>(n1) - static_cast<cast_type>(n2) * c;
1231    BOOST_CHECK_EQUAL(d ,  -20 - -3 * -4);
1232    d = static_cast<cast_type>(n1) - b * static_cast<cast_type>(n3);
1233    BOOST_CHECK_EQUAL(d ,  -20 - -3 * -4);
1234    a -= static_cast<cast_type>(n2) * c;
1235    BOOST_CHECK_EQUAL(a ,  -20 - -3 * -4);
1236    a = static_cast<cast_type>(n1);
1237    a -= b * static_cast<cast_type>(n3);
1238    BOOST_CHECK_EQUAL(a ,  -20 - -3 * -4);
1239 
1240    a = -2;
1241    d = b * c - a;
1242    BOOST_CHECK_EQUAL(d ,  -3 * -4 - -2);
1243    n1 = -2;
1244    d = b * c - static_cast<cast_type>(n1);
1245    BOOST_CHECK_EQUAL(d ,  -3 * -4 - -2);
1246    d = static_cast<cast_type>(n2) * c - a;
1247    BOOST_CHECK_EQUAL(d ,  -3 * -4 - -2);
1248    d = b * static_cast<cast_type>(n3) - a;
1249    BOOST_CHECK_EQUAL(d ,  -3 * -4 - -2);
1250    d = static_cast<cast_type>(n2) * c - static_cast<cast_type>(n1);
1251    BOOST_CHECK_EQUAL(d ,  -3 * -4 - -2);
1252    d = b * static_cast<cast_type>(n3) - static_cast<cast_type>(n1);
1253    BOOST_CHECK_EQUAL(d ,  -3 * -4 - -2);
1254    //
1255    // Conversion from min and max values:
1256    //
1257    test_negative_mixed_minmax<Real, Num>(boost::mpl::bool_<std::numeric_limits<Real>::is_integer && std::numeric_limits<Num>::is_integer>());
1258 }
1259 
1260 template <class Real, class Num>
test_negative_mixed(boost::mpl::false_ const &)1261 void test_negative_mixed(boost::mpl::false_ const&)
1262 {
1263 }
1264 
1265 template <class Real, class Num>
test_mixed(const boost::mpl::false_ &)1266 void test_mixed(const boost::mpl::false_&)
1267 {
1268 }
1269 
1270 template <class Real, class Num>
test_mixed(const boost::mpl::true_ &)1271 void test_mixed(const boost::mpl::true_&)
1272 {
1273    typedef typename lexical_cast_target_type<Num>::type target_type;
1274    typedef typename boost::mpl::if_<
1275          boost::is_convertible<Num, Real>,
1276          typename boost::mpl::if_c<boost::is_integral<Num>::value && (sizeof(Num) < sizeof(int)), int, Num>::type,
1277          Real
1278       >::type cast_type;
1279    typedef typename boost::mpl::if_<
1280          boost::is_convertible<Num, Real>,
1281          Num,
1282          Real
1283       >::type simple_cast_type;
1284 
1285    if(std::numeric_limits<Real>::is_specialized && std::numeric_limits<Real>::is_bounded && std::numeric_limits<Real>::digits < std::numeric_limits<Num>::digits)
1286       return;
1287 
1288    std::cout << "Testing mixed arithmetic with type: " << typeid(Real).name()  << " and " << typeid(Num).name() << std::endl;
1289    static const int left_shift = std::numeric_limits<Num>::digits - 1;
1290    Num n1 = static_cast<Num>(1uLL << ((left_shift < 63) && (left_shift > 0) ? left_shift : 10));
1291    Num n2 = 1;
1292    Num n3 = 0;
1293    Num n4 = 20;
1294    Num n5 = 8;
1295 
1296    test_comparisons<Real>(n1, n2, boost::is_convertible<Num, Real>());
1297    test_comparisons<Real>(n1, n3, boost::is_convertible<Num, Real>());
1298    test_comparisons<Real>(n1, n1, boost::is_convertible<Num, Real>());
1299    test_comparisons<Real>(n3, n1, boost::is_convertible<Num, Real>());
1300    test_comparisons<Real>(n2, n1, boost::is_convertible<Num, Real>());
1301    test_comparisons<Real>(n3, n3, boost::is_convertible<Num, Real>());
1302 
1303    // Default construct:
1304    BOOST_CHECK_EQUAL(Real(n1) ,  static_cast<cast_type>(n1));
1305    BOOST_CHECK_EQUAL(Real(n2) ,  static_cast<cast_type>(n2));
1306    BOOST_CHECK_EQUAL(Real(n3) ,  static_cast<cast_type>(n3));
1307    BOOST_CHECK_EQUAL(Real(n4) ,  static_cast<cast_type>(n4));
1308    BOOST_CHECK_EQUAL(Real(n1).template convert_to<Num>() ,  n1);
1309    BOOST_CHECK_EQUAL(Real(n2).template convert_to<Num>() ,  n2);
1310    BOOST_CHECK_EQUAL(Real(n3).template convert_to<Num>() ,  n3);
1311    BOOST_CHECK_EQUAL(Real(n4).template convert_to<Num>() ,  n4);
1312 #ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
1313    BOOST_CHECK_EQUAL(static_cast<Num>(Real(n1)) ,  n1);
1314    BOOST_CHECK_EQUAL(static_cast<Num>(Real(n2)) ,  n2);
1315    BOOST_CHECK_EQUAL(static_cast<Num>(Real(n3)) ,  n3);
1316    BOOST_CHECK_EQUAL(static_cast<Num>(Real(n4)) ,  n4);
1317 #endif
1318    BOOST_CHECK_EQUAL(static_cast<cast_type>(n1) ,  Real(n1));
1319    BOOST_CHECK_EQUAL(static_cast<cast_type>(n2) ,  Real(n2));
1320    BOOST_CHECK_EQUAL(static_cast<cast_type>(n3) ,  Real(n3));
1321    BOOST_CHECK_EQUAL(static_cast<cast_type>(n4) ,  Real(n4));
1322 #if defined(TEST_MPFR)
1323    Num tol = 10 * std::numeric_limits<Num>::epsilon();
1324 #else
1325    Num tol = 0;
1326 #endif
1327    std::ios_base::fmtflags f = boost::is_floating_point<Num>::value ? std::ios_base::scientific : std::ios_base::fmtflags(0);
1328    int digits_to_print = boost::is_floating_point<Num>::value && std::numeric_limits<Num>::is_specialized
1329       ? std::numeric_limits<Num>::digits10 + 5 : 0;
1330    if(std::numeric_limits<target_type>::digits <= std::numeric_limits<Real>::digits)
1331    {
1332       BOOST_CHECK_CLOSE(n1, checked_lexical_cast<target_type>(Real(n1).str(digits_to_print, f)), tol);
1333    }
1334    BOOST_CHECK_CLOSE(n2, checked_lexical_cast<target_type>(Real(n2).str(digits_to_print, f)), 0);
1335    BOOST_CHECK_CLOSE(n3, checked_lexical_cast<target_type>(Real(n3).str(digits_to_print, f)), 0);
1336    BOOST_CHECK_CLOSE(n4, checked_lexical_cast<target_type>(Real(n4).str(digits_to_print, f)), 0);
1337    // Assignment:
1338    Real r(0);
1339    BOOST_CHECK(r != static_cast<cast_type>(n1));
1340    r = static_cast<simple_cast_type>(n1);
1341    BOOST_CHECK_EQUAL(r ,  static_cast<cast_type>(n1));
1342    r = static_cast<simple_cast_type>(n2);
1343    BOOST_CHECK_EQUAL(r ,  static_cast<cast_type>(n2));
1344    r = static_cast<simple_cast_type>(n3);
1345    BOOST_CHECK_EQUAL(r ,  static_cast<cast_type>(n3));
1346    r = static_cast<simple_cast_type>(n4);
1347    BOOST_CHECK_EQUAL(r ,  static_cast<cast_type>(n4));
1348    // Addition:
1349    r = static_cast<simple_cast_type>(n2);
1350    BOOST_CHECK_EQUAL(r + static_cast<simple_cast_type>(n4) ,  static_cast<cast_type>(n2 + n4));
1351    BOOST_CHECK_EQUAL(Real(r + static_cast<simple_cast_type>(n4)) ,  static_cast<cast_type>(n2 + n4));
1352    r += static_cast<simple_cast_type>(n4);
1353    BOOST_CHECK_EQUAL(r ,  static_cast<cast_type>(n2 + n4));
1354    // subtraction:
1355    r = static_cast<simple_cast_type>(n4);
1356    BOOST_CHECK_EQUAL(r - static_cast<simple_cast_type>(n5) ,  static_cast<cast_type>(n4 - n5));
1357    BOOST_CHECK_EQUAL(Real(r - static_cast<simple_cast_type>(n5)) ,  static_cast<cast_type>(n4 - n5));
1358    r -= static_cast<simple_cast_type>(n5);
1359    BOOST_CHECK_EQUAL(r ,  static_cast<cast_type>(n4 - n5));
1360    // Multiplication:
1361    r = static_cast<simple_cast_type>(n2);
1362    BOOST_CHECK_EQUAL(r * static_cast<simple_cast_type>(n4) ,  static_cast<cast_type>(n2 * n4));
1363    BOOST_CHECK_EQUAL(Real(r * static_cast<simple_cast_type>(n4)) ,  static_cast<cast_type>(n2 * n4));
1364    r *= static_cast<simple_cast_type>(n4);
1365    BOOST_CHECK_EQUAL(r ,  static_cast<cast_type>(n2 * n4));
1366    // Division:
1367    r = static_cast<simple_cast_type>(n1);
1368    BOOST_CHECK_EQUAL(r / static_cast<simple_cast_type>(n5) ,  static_cast<cast_type>(n1 / n5));
1369    BOOST_CHECK_EQUAL(Real(r / static_cast<simple_cast_type>(n5)) ,  static_cast<cast_type>(n1 / n5));
1370    r /= static_cast<simple_cast_type>(n5);
1371    BOOST_CHECK_EQUAL(r ,  static_cast<cast_type>(n1 / n5));
1372    //
1373    // special cases for full coverage:
1374    //
1375    r = static_cast<simple_cast_type>(n5) + Real(n4);
1376    BOOST_CHECK_EQUAL(r ,  static_cast<cast_type>(n4 + n5));
1377    r = static_cast<simple_cast_type>(n4) - Real(n5);
1378    BOOST_CHECK_EQUAL(r ,  static_cast<cast_type>(n4 - n5));
1379    r = static_cast<simple_cast_type>(n4) * Real(n5);
1380    BOOST_CHECK_EQUAL(r ,  static_cast<cast_type>(n4 * n5));
1381    r = static_cast<cast_type>(4 * n4) / Real(4);
1382    BOOST_CHECK_EQUAL(r ,  static_cast<cast_type>(n4));
1383 
1384    typedef boost::mpl::bool_<
1385       (!std::numeric_limits<Num>::is_specialized || std::numeric_limits<Num>::is_signed)
1386       && (!std::numeric_limits<Real>::is_specialized || std::numeric_limits<Real>::is_signed)> signed_tag;
1387 
1388    test_negative_mixed<Real, Num>(signed_tag());
1389 
1390    n1 = 2;
1391    n2 = 3;
1392    n3 = 4;
1393    Real a(n1), b(n2), c(n3), d;
1394    d = a + b * c;
1395    BOOST_CHECK_EQUAL(d ,  2 + 3 * 4);
1396    d = static_cast<cast_type>(n1) + b * c;
1397    BOOST_CHECK_EQUAL(d ,  2 + 3 * 4);
1398    d = a + static_cast<cast_type>(n2) * c;
1399    BOOST_CHECK_EQUAL(d ,  2 + 3 * 4);
1400    d = a + b * static_cast<cast_type>(n3);
1401    BOOST_CHECK_EQUAL(d ,  2 + 3 * 4);
1402    d = static_cast<cast_type>(n1) + static_cast<cast_type>(n2) * c;
1403    BOOST_CHECK_EQUAL(d ,  2 + 3 * 4);
1404    d = static_cast<cast_type>(n1) + b * static_cast<cast_type>(n3);
1405    BOOST_CHECK_EQUAL(d ,  2 + 3 * 4);
1406    a += static_cast<cast_type>(n2) * c;
1407    BOOST_CHECK_EQUAL(a ,  2 + 3 * 4);
1408    a = static_cast<cast_type>(n1);
1409    a += b * static_cast<cast_type>(n3);
1410    BOOST_CHECK_EQUAL(a ,  2 + 3 * 4);
1411    a = static_cast<cast_type>(n1);
1412 
1413    d = b * c + a;
1414    BOOST_CHECK_EQUAL(d ,  2 + 3 * 4);
1415    d = b * c + static_cast<cast_type>(n1);
1416    BOOST_CHECK_EQUAL(d ,  2 + 3 * 4);
1417    d = static_cast<cast_type>(n2) * c + a;
1418    BOOST_CHECK_EQUAL(d ,  2 + 3 * 4);
1419    d = b * static_cast<cast_type>(n3) + a;
1420    BOOST_CHECK_EQUAL(d ,  2 + 3 * 4);
1421    d = static_cast<cast_type>(n2) * c + static_cast<cast_type>(n1);
1422    BOOST_CHECK_EQUAL(d ,  2 + 3 * 4);
1423    d = b * static_cast<cast_type>(n3) + static_cast<cast_type>(n1);
1424    BOOST_CHECK_EQUAL(d ,  2 + 3 * 4);
1425 
1426    a = 20;
1427    d = a - b * c;
1428    BOOST_CHECK_EQUAL(d ,  20 - 3 * 4);
1429    n1 = 20;
1430    d = static_cast<cast_type>(n1) - b * c;
1431    BOOST_CHECK_EQUAL(d ,  20 - 3 * 4);
1432    d = a - static_cast<cast_type>(n2) * c;
1433    BOOST_CHECK_EQUAL(d ,  20 - 3 * 4);
1434    d = a - b * static_cast<cast_type>(n3);
1435    BOOST_CHECK_EQUAL(d ,  20 - 3 * 4);
1436    d = static_cast<cast_type>(n1) - static_cast<cast_type>(n2) * c;
1437    BOOST_CHECK_EQUAL(d ,  20 - 3 * 4);
1438    d = static_cast<cast_type>(n1) - b * static_cast<cast_type>(n3);
1439    BOOST_CHECK_EQUAL(d ,  20 - 3 * 4);
1440    a -= static_cast<cast_type>(n2) * c;
1441    BOOST_CHECK_EQUAL(a ,  20 - 3 * 4);
1442    a = static_cast<cast_type>(n1);
1443    a -= b * static_cast<cast_type>(n3);
1444    BOOST_CHECK_EQUAL(a ,  20 - 3 * 4);
1445 
1446    a = 2;
1447    d = b * c - a;
1448    BOOST_CHECK_EQUAL(d ,  3 * 4 - 2);
1449    n1 = 2;
1450    d = b * c - static_cast<cast_type>(n1);
1451    BOOST_CHECK_EQUAL(d ,  3 * 4 - 2);
1452    d = static_cast<cast_type>(n2) * c - a;
1453    BOOST_CHECK_EQUAL(d ,  3 * 4 - 2);
1454    d = b * static_cast<cast_type>(n3) - a;
1455    BOOST_CHECK_EQUAL(d ,  3 * 4 - a);
1456    d = static_cast<cast_type>(n2) * c - static_cast<cast_type>(n1);
1457    BOOST_CHECK_EQUAL(d ,  3 * 4 - 2);
1458    d = b * static_cast<cast_type>(n3) - static_cast<cast_type>(n1);
1459    BOOST_CHECK_EQUAL(d ,  3 * 4 - 2);
1460 }
1461 
1462 template <class Real>
test_members(Real)1463 void test_members(Real)
1464 {
1465    //
1466    // Test sign and zero functions:
1467    //
1468    Real a = 20;
1469    Real b = 30;
1470    BOOST_CHECK(a.sign() > 0);
1471    BOOST_CHECK(!a.is_zero());
1472    if(std::numeric_limits<Real>::is_signed)
1473    {
1474       a = -20;
1475       BOOST_CHECK(a.sign() < 0);
1476       BOOST_CHECK(!a.is_zero());
1477    }
1478    a = 0;
1479    BOOST_CHECK_EQUAL(a.sign() ,  0);
1480    BOOST_CHECK(a.is_zero());
1481 
1482    a = 20;
1483    b = 30;
1484    a.swap(b);
1485    BOOST_CHECK_EQUAL(a ,  30);
1486    BOOST_CHECK_EQUAL(b ,  20);
1487 }
1488 
1489 template <class Real>
test_members(boost::rational<Real>)1490 void test_members(boost::rational<Real>)
1491 {
1492 }
1493 
1494 template <class Real>
test_signed_ops(const boost::mpl::true_ &)1495 void test_signed_ops(const boost::mpl::true_&)
1496 {
1497    Real a(8);
1498    Real b(64);
1499    Real c(500);
1500    Real d(1024);
1501    Real ac;
1502    BOOST_CHECK_EQUAL(-a ,  -8);
1503    ac = a;
1504    ac = ac - b;
1505    BOOST_CHECK_EQUAL(ac ,  8 - 64);
1506    ac = a;
1507    ac -= a + b;
1508    BOOST_CHECK_EQUAL(ac ,  -64);
1509    ac = a;
1510    ac -= b - a;
1511    BOOST_CHECK_EQUAL(ac ,  16 - 64);
1512    ac = -a;
1513    BOOST_CHECK_EQUAL(ac ,  -8);
1514    ac = a;
1515    ac -= -a;
1516    BOOST_CHECK_EQUAL(ac ,  16);
1517    ac = a;
1518    ac += -a;
1519    BOOST_CHECK_EQUAL(ac ,  0);
1520    ac = b;
1521    ac /= -a;
1522    BOOST_CHECK_EQUAL(ac ,  -8);
1523    ac = a;
1524    ac *= -a;
1525    BOOST_CHECK_EQUAL(ac ,  -64);
1526    ac = a + -b;
1527    BOOST_CHECK_EQUAL(ac ,  8 - 64);
1528    ac = -a + b;
1529    BOOST_CHECK_EQUAL(ac ,  -8+64);
1530    ac = -a + -b;
1531    BOOST_CHECK_EQUAL(ac ,  -72);
1532    ac = a + - + -b; // lots of unary operators!!
1533    BOOST_CHECK_EQUAL(ac ,  72);
1534    test_conditional(Real(-a), -a);
1535 }
1536 template <class Real>
test_signed_ops(const boost::mpl::false_ &)1537 void test_signed_ops(const boost::mpl::false_&)
1538 {
1539 }
1540 
1541 template <class Real>
test()1542 void test()
1543 {
1544 #if !defined(NO_MIXED_OPS) && !defined(SLOW_COMPILER)
1545    boost::multiprecision::is_number<Real> tag;
1546    test_mixed<Real, unsigned char>(tag);
1547    test_mixed<Real, signed char>(tag);
1548    test_mixed<Real, char>(tag);
1549    test_mixed<Real, short>(tag);
1550    test_mixed<Real, unsigned short>(tag);
1551    test_mixed<Real, int>(tag);
1552    test_mixed<Real, unsigned int>(tag);
1553    test_mixed<Real, long>(tag);
1554    test_mixed<Real, unsigned long>(tag);
1555 #ifdef BOOST_HAS_LONG_LONG
1556    test_mixed<Real, long long>(tag);
1557    test_mixed<Real, unsigned long long>(tag);
1558 #endif
1559    test_mixed<Real, float>(tag);
1560    test_mixed<Real, double>(tag);
1561    test_mixed<Real, long double>(tag);
1562 
1563    typedef typename related_type<Real>::type related_type;
1564    boost::mpl::bool_<boost::multiprecision::is_number<Real>::value && !boost::is_same<related_type, Real>::value>  tag2;
1565 
1566    test_mixed<Real, related_type>(tag2);
1567 
1568 #endif
1569    //
1570    // Integer only functions:
1571    //
1572    test_integer_ops<Real>(typename boost::multiprecision::number_category<Real>::type());
1573    //
1574    // Real number only functions:
1575    //
1576    test_float_ops<Real>(typename boost::multiprecision::number_category<Real>::type());
1577    //
1578    // Test basic arithmetic:
1579    //
1580    Real a(8);
1581    Real b(64);
1582    Real c(500);
1583    Real d(1024);
1584    BOOST_CHECK_EQUAL(a + b ,  72);
1585    a += b;
1586    BOOST_CHECK_EQUAL(a ,  72);
1587    BOOST_CHECK_EQUAL(a - b ,  8);
1588    a -= b;
1589    BOOST_CHECK_EQUAL(a ,  8);
1590    BOOST_CHECK_EQUAL(a * b ,  8*64L);
1591    a *= b;
1592    BOOST_CHECK_EQUAL(a ,  8*64L);
1593    BOOST_CHECK_EQUAL(a / b ,  8);
1594    a /= b;
1595    BOOST_CHECK_EQUAL(a ,  8);
1596    Real ac(a);
1597    BOOST_CHECK_EQUAL(ac ,  a);
1598    ac = a * c;
1599    BOOST_CHECK_EQUAL(ac ,  8*500L);
1600    ac = 8*500L;
1601    ac = ac + b + c;
1602    BOOST_CHECK_EQUAL(ac ,  8*500L+64+500);
1603    ac = a;
1604    ac = b + c + ac;
1605    BOOST_CHECK_EQUAL(ac ,  8+64+500);
1606    ac = ac - b + c;
1607    BOOST_CHECK_EQUAL(ac ,  8+64+500-64+500);
1608    ac = a;
1609    ac = b + c - ac;
1610    BOOST_CHECK_EQUAL(ac ,  -8+64+500);
1611    ac = a;
1612    ac = ac * b;
1613    BOOST_CHECK_EQUAL(ac ,  8*64);
1614    ac = a;
1615    ac *= b * ac;
1616    BOOST_CHECK_EQUAL(ac ,  8*8*64);
1617    ac = b;
1618    ac = ac / a;
1619    BOOST_CHECK_EQUAL(ac ,  64/8);
1620    ac = b;
1621    ac /= ac / a;
1622    BOOST_CHECK_EQUAL(ac ,  64 / (64/8));
1623    ac = a;
1624    ac = b + ac * a;
1625    BOOST_CHECK_EQUAL(ac ,  64 * 2);
1626    ac = a;
1627    ac = b - ac * a;
1628    BOOST_CHECK_EQUAL(ac ,  0);
1629    ac = a;
1630    ac = b * (ac + a);
1631    BOOST_CHECK_EQUAL(ac ,  64 * (16));
1632    ac = a;
1633    ac = b / (ac * 1);
1634    BOOST_CHECK_EQUAL(ac ,  64 / 8);
1635    ac = a;
1636    ac = ac + b;
1637    BOOST_CHECK_EQUAL(ac ,  8 + 64);
1638    ac = a;
1639    ac = a + ac;
1640    BOOST_CHECK_EQUAL(ac ,  16);
1641    ac = a;
1642    ac = a - ac;
1643    BOOST_CHECK_EQUAL(ac ,  0);
1644    ac = a;
1645    ac += a + b;
1646    BOOST_CHECK_EQUAL(ac ,  80);
1647    ac = a;
1648    ac += b + a;
1649    BOOST_CHECK_EQUAL(ac ,  80);
1650    ac = +a;
1651    BOOST_CHECK_EQUAL(ac ,  8);
1652    ac = 8;
1653    ac = a * ac;
1654    BOOST_CHECK_EQUAL(ac ,  8*8);
1655    ac = a;
1656    ac = a;
1657    ac += +a;
1658    BOOST_CHECK_EQUAL(ac ,  16);
1659    ac = a;
1660    ac += b - a;
1661    BOOST_CHECK_EQUAL(ac ,  8 + 64-8);
1662    ac = a;
1663    ac += b*c;
1664    BOOST_CHECK_EQUAL(ac ,  8 + 64 * 500);
1665    ac = a;
1666    ac = a;
1667    ac -= +a;
1668    BOOST_CHECK_EQUAL(ac ,  0);
1669    ac = a;
1670    if(std::numeric_limits<Real>::is_signed || is_twos_complement_integer<Real>::value)
1671    {
1672       ac = a;
1673       ac -= c - b;
1674       BOOST_CHECK_EQUAL(ac ,  8 - (500-64));
1675       ac = a;
1676       ac -= b*c;
1677       BOOST_CHECK_EQUAL(ac ,  8 - 500*64);
1678    }
1679    ac = a;
1680    ac += ac * b;
1681    BOOST_CHECK_EQUAL(ac ,  8 + 8 * 64);
1682    if(std::numeric_limits<Real>::is_signed || is_twos_complement_integer<Real>::value)
1683    {
1684       ac = a;
1685       ac -= ac * b;
1686       BOOST_CHECK_EQUAL(ac ,  8 - 8 * 64);
1687    }
1688    ac = a * 8;
1689    ac *= +a;
1690    BOOST_CHECK_EQUAL(ac ,  64 * 8);
1691    ac = a;
1692    ac *= b * c;
1693    BOOST_CHECK_EQUAL(ac ,  8 * 64 * 500);
1694    ac = a;
1695    ac *= b / a;
1696    BOOST_CHECK_EQUAL(ac ,  8 * 64 / 8);
1697    ac = a;
1698    ac *= b + c;
1699    BOOST_CHECK_EQUAL(ac ,  8 * (64 + 500));
1700    ac = b;
1701    ac /= +a;
1702    BOOST_CHECK_EQUAL(ac ,  8);
1703    ac = b;
1704    ac /= b / a;
1705    BOOST_CHECK_EQUAL(ac ,  64 / (64/8));
1706    ac = b;
1707    ac /= a + Real(0);
1708    BOOST_CHECK_EQUAL(ac ,  8);
1709    //
1710    // simple tests with immediate values, these calls can be optimised in many backends:
1711    //
1712    ac = a + b;
1713    BOOST_CHECK_EQUAL(ac ,  72);
1714    ac = a + +b;
1715    BOOST_CHECK_EQUAL(ac ,  72);
1716    ac = +a + b;
1717    BOOST_CHECK_EQUAL(ac ,  72);
1718    ac = +a + +b;
1719    BOOST_CHECK_EQUAL(ac ,  72);
1720    ac = a;
1721    ac = b / ac;
1722    BOOST_CHECK_EQUAL(ac ,  b / a);
1723    //
1724    // Comparisons:
1725    //
1726    BOOST_CHECK_EQUAL((a == b) ,  false);
1727    BOOST_CHECK_EQUAL((a != b) ,  true);
1728    BOOST_CHECK_EQUAL((a <= b) ,  true);
1729    BOOST_CHECK_EQUAL((a < b) ,  true);
1730    BOOST_CHECK_EQUAL((a >= b) ,  false);
1731    BOOST_CHECK_EQUAL((a > b) ,  false);
1732 
1733    BOOST_CHECK_EQUAL((a+b == b) ,  false);
1734    BOOST_CHECK_EQUAL((a+b != b) ,  true);
1735    BOOST_CHECK_EQUAL((a+b >= b) ,  true);
1736    BOOST_CHECK_EQUAL((a+b > b) ,  true);
1737    BOOST_CHECK_EQUAL((a+b <= b) ,  false);
1738    BOOST_CHECK_EQUAL((a+b < b) ,  false);
1739 
1740    BOOST_CHECK_EQUAL((a == b+a) ,  false);
1741    BOOST_CHECK_EQUAL((a != b+a) ,  true);
1742    BOOST_CHECK_EQUAL((a <= b+a) ,  true);
1743    BOOST_CHECK_EQUAL((a < b+a) ,  true);
1744    BOOST_CHECK_EQUAL((a >= b+a) ,  false);
1745    BOOST_CHECK_EQUAL((a > b+a) ,  false);
1746 
1747    BOOST_CHECK_EQUAL((a+b == b+a) ,  true);
1748    BOOST_CHECK_EQUAL((a+b != b+a) ,  false);
1749    BOOST_CHECK_EQUAL((a+b <= b+a) ,  true);
1750    BOOST_CHECK_EQUAL((a+b < b+a) ,  false);
1751    BOOST_CHECK_EQUAL((a+b >= b+a) ,  true);
1752    BOOST_CHECK_EQUAL((a+b > b+a) ,  false);
1753 
1754    BOOST_CHECK_EQUAL((8 == b+a) ,  false);
1755    BOOST_CHECK_EQUAL((8 != b+a) ,  true);
1756    BOOST_CHECK_EQUAL((8 <= b+a) ,  true);
1757    BOOST_CHECK_EQUAL((8 < b+a) ,  true);
1758    BOOST_CHECK_EQUAL((8 >= b+a) ,  false);
1759    BOOST_CHECK_EQUAL((8 > b+a) ,  false);
1760    BOOST_CHECK_EQUAL((800 == b+a) ,  false);
1761    BOOST_CHECK_EQUAL((800 != b+a) ,  true);
1762    BOOST_CHECK_EQUAL((800 >= b+a) ,  true);
1763    BOOST_CHECK_EQUAL((800 > b+a) ,  true);
1764    BOOST_CHECK_EQUAL((800 <= b+a) ,  false);
1765    BOOST_CHECK_EQUAL((800 < b+a) ,  false);
1766    BOOST_CHECK_EQUAL((72 == b+a) ,  true);
1767    BOOST_CHECK_EQUAL((72 != b+a) ,  false);
1768    BOOST_CHECK_EQUAL((72 <= b+a) ,  true);
1769    BOOST_CHECK_EQUAL((72 < b+a) ,  false);
1770    BOOST_CHECK_EQUAL((72 >= b+a) ,  true);
1771    BOOST_CHECK_EQUAL((72 > b+a) ,  false);
1772 
1773    test_members(a);
1774    //
1775    // Use in Boolean context:
1776    //
1777    a = 0;
1778    if(a)
1779    {
1780       BOOST_ERROR("Unexpected non-zero result");
1781    }
1782    if(!a){}
1783    else
1784    {
1785       BOOST_ERROR("Unexpected zero result");
1786    }
1787    b = 2;
1788    if(!b)
1789    {
1790       BOOST_ERROR("Unexpected zero result");
1791    }
1792    if(b){}
1793    else
1794    {
1795       BOOST_ERROR("Unexpected non-zero result");
1796    }
1797    if(a && b)
1798    {
1799       BOOST_ERROR("Unexpected zero result");
1800    }
1801    if(!(a || b))
1802    {
1803       BOOST_ERROR("Unexpected zero result");
1804    }
1805    if(a + b){}
1806    else
1807    {
1808       BOOST_ERROR("Unexpected zero result");
1809    }
1810    if(b - 2)
1811    {
1812       BOOST_ERROR("Unexpected non-zero result");
1813    }
1814    //
1815    // Test iostreams:
1816    //
1817    std::stringstream ss;
1818    a = 20;
1819    b = 2;
1820    ss << a;
1821    ss >> c;
1822    BOOST_CHECK_EQUAL(a ,  c);
1823    ss.clear();
1824    ss << a + b;
1825    ss >> c;
1826    BOOST_CHECK_EQUAL(c ,  22);
1827    BOOST_CHECK_EQUAL(c ,  a + b);
1828    //
1829    // More cases for complete code coverage:
1830    //
1831    a = 20;
1832    b = 30;
1833    swap(a, b);
1834    BOOST_CHECK_EQUAL(a ,  30);
1835    BOOST_CHECK_EQUAL(b ,  20);
1836    a = 20;
1837    b = 30;
1838    std::swap(a, b);
1839    BOOST_CHECK_EQUAL(a ,  30);
1840    BOOST_CHECK_EQUAL(b ,  20);
1841    a = 20;
1842    b = 30;
1843    a = a + b * 2;
1844    BOOST_CHECK_EQUAL(a ,  20 + 30 * 2);
1845    a = 100;
1846    a = a - b * 2;
1847    BOOST_CHECK_EQUAL(a ,  100 - 30 * 2);
1848    a = 20;
1849    a = a * (b + 2);
1850    BOOST_CHECK_EQUAL(a ,  20 * (32));
1851    a = 20;
1852    a = (b + 2) * a;
1853    BOOST_CHECK_EQUAL(a ,  20 * (32));
1854    a = 90;
1855    b = 2;
1856    a = a / (b + 0);
1857    BOOST_CHECK_EQUAL(a ,  45);
1858    a = 20;
1859    b = 30;
1860    c = (a * b) + 22;
1861    BOOST_CHECK_EQUAL(c ,  20 * 30 + 22);
1862    c = 22 + (a * b);
1863    BOOST_CHECK_EQUAL(c ,  20 * 30 + 22);
1864    c = 10;
1865    ac = a + b * c;
1866    BOOST_CHECK_EQUAL(ac ,  20 + 30 * 10);
1867    ac = b * c + a;
1868    BOOST_CHECK_EQUAL(ac ,  20 + 30 * 10);
1869    a = a + b * c;
1870    BOOST_CHECK_EQUAL(a ,  20 + 30 * 10);
1871    a = 20;
1872    b = a + b * c;
1873    BOOST_CHECK_EQUAL(b ,  20 + 30 * 10);
1874    b = 30;
1875    c = a + b * c;
1876    BOOST_CHECK_EQUAL(c ,  20 + 30 * 10);
1877    c = 10;
1878    c = a + b / c;
1879    BOOST_CHECK_EQUAL(c ,  20 + 30 / 10);
1880 
1881    //
1882    // Test conditionals:
1883    //
1884    a = 20;
1885    test_conditional(a, +a);
1886    test_conditional(a, (a + 0));
1887 
1888    test_signed_ops<Real>(boost::mpl::bool_<std::numeric_limits<Real>::is_signed>());
1889    //
1890    // Test move:
1891    //
1892 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1893    Real m(static_cast<Real&&>(a));
1894    BOOST_CHECK_EQUAL(m, 20);
1895    // Move from already moved from object:
1896    Real m2(static_cast<Real&&>(a));
1897    // assign from moved from object
1898    // (may result in "a" being left in valid state as implementation artifact):
1899    c = static_cast<Real&&>(a);
1900    // assignment to moved-from objects:
1901    c = static_cast<Real&&>(m);
1902    BOOST_CHECK_EQUAL(c, 20);
1903    m2 = c;
1904    BOOST_CHECK_EQUAL(c, 20);
1905    // Destructor of "a" checks destruction of moved-from-object...
1906    Real m3(static_cast<Real&&>(a));
1907 #endif
1908    //
1909    // Bug cases, self assignment first:
1910    //
1911    a = 20;
1912    a = a;
1913    BOOST_CHECK_EQUAL(a, 20);
1914 }
1915 
1916