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