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_
10 #include <boost/math/special_functions/pow.hpp>
11 #include <boost/math/common_factor_rt.hpp>
15 struct is_boost_rational : public boost::mpl::false_{};
17 struct is_checked_cpp_int : public boost::mpl::false_ {};
20 // warning C4127: conditional expression is constant
21 #pragma warning(disable:4127)
24 template <class Target, class Source>
25 Target checked_lexical_cast(const Source& val)
27 #ifndef BOOST_NO_EXCEPTIONS
31 return boost::lexical_cast<Target>(val);
32 #ifndef BOOST_NO_EXCEPTIONS
36 std::cerr << "Error in lexical cast\nSource type = " << typeid(Source).name() << " \"" << val << "\"\n";
37 std::cerr << "Target type = " << typeid(Target).name() << std::endl;
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; }
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)
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);
62 struct is_twos_complement_integer : public boost::mpl::true_ {};
70 template <class Real, class Val>
71 void test_comparisons(Val, Val, const boost::mpl::false_)
74 int normalize_compare_result(int r)
76 return r > 0 ? 1 : r < 0 ? -1 : 0;
79 template <class Real, class Val>
80 void test_comparisons(Val a, Val b, const boost::mpl::true_)
86 int cr = a < b ? -1 : a > b ? 1 : 0;
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);
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);
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);
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);
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);
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);
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);
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);
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);
150 template <class Real, class Exp>
151 void test_conditional(Real v, Exp e)
154 // Verify that Exp is usable in Boolean contexts, and has the same value as v:
174 template <class Real>
175 void test_complement(Real a, Real b, Real c, const boost::mpl::true_&)
180 if(std::numeric_limits<Real>::is_signed)
182 BOOST_CHECK_EQUAL(~a , (~i & sign_mask));
184 BOOST_CHECK_EQUAL(c , (i & (~j & sign_mask)));
186 BOOST_CHECK_EQUAL(c , (~(i | j) & sign_mask));
190 BOOST_CHECK_EQUAL((~a & a) , 0);
194 template <class Real>
195 void test_complement(Real, Real, Real, const boost::mpl::false_&)
199 template <class Real, class T>
200 void test_integer_ops(const T&){}
202 template <class Real>
203 void test_rational(const boost::mpl::true_&)
207 BOOST_CHECK_EQUAL(numerator(a) , 2);
208 BOOST_CHECK_EQUAL(denominator(a) , 3);
211 BOOST_CHECK_EQUAL(a , b);
216 std::stringstream ss;
219 BOOST_CHECK_EQUAL(a, b);
222 template <class Real>
223 void test_rational(const boost::mpl::false_&)
227 BOOST_CHECK_EQUAL(numerator(a) , 2);
228 BOOST_CHECK_EQUAL(denominator(a) , 3);
231 BOOST_CHECK_EQUAL(a , b);
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);
238 BOOST_CHECK_EQUAL(a, b);
242 std::stringstream ss;
245 BOOST_CHECK_EQUAL(a, b);
248 template <class Real>
249 void test_integer_ops(const boost::mpl::int_<boost::multiprecision::number_kind_rational>&)
251 test_rational<Real>(is_boost_rational<Real>());
254 template <class Real>
255 void test_signed_integer_ops(const boost::mpl::true_&)
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);
274 BOOST_CHECK_EQUAL(a % b , 20 % -7);
276 BOOST_CHECK_EQUAL(a % b , -20 % -7);
277 BOOST_CHECK_EQUAL(a % -7 , -20 % -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);
285 BOOST_CHECK_EQUAL(a , 20 % 7);
288 BOOST_CHECK_EQUAL(a , -20 % 7);
291 BOOST_CHECK_EQUAL(a , 20 % -7);
294 BOOST_CHECK_EQUAL(a , -20 % -7);
297 BOOST_CHECK_EQUAL(a , 5 % (7-5));
300 BOOST_CHECK_EQUAL(a , -20 % 7);
303 BOOST_CHECK_EQUAL(a , 20 % -7);
306 BOOST_CHECK_EQUAL(a , -20 % -7);
307 #ifndef BOOST_NO_LONG_LONG
310 BOOST_CHECK_EQUAL(a , -20 % 7);
313 BOOST_CHECK_EQUAL(a , 20 % -7);
316 BOOST_CHECK_EQUAL(a , -20 % -7);
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));
325 BOOST_CHECK_EQUAL(abs(a) , 20);
326 BOOST_CHECK_EQUAL(abs(-a) , 20);
327 BOOST_CHECK_EQUAL(abs(+a) , 20);
329 BOOST_CHECK_EQUAL(abs(a) , 20);
330 BOOST_CHECK_EQUAL(abs(-a) , 20);
331 BOOST_CHECK_EQUAL(abs(+a) , 20);
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));
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));
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));
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)
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);
369 BOOST_CHECK_EQUAL(a << 10, (boost::intmax_t(-1) << 10));
371 BOOST_CHECK_EQUAL(a << 10, (boost::intmax_t(-23) << 10));
373 BOOST_CHECK_EQUAL(a >> 10, (boost::intmax_t(-23456) >> 10));
375 BOOST_CHECK_EQUAL(a >> 10, (boost::intmax_t(-3) >> 10));
379 template <class Real>
380 void test_signed_integer_ops(const boost::mpl::false_&)
384 template <class Real, class Int>
385 void test_integer_round_trip()
387 if(std::numeric_limits<Real>::digits >= std::numeric_limits<Int>::digits)
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))
394 m = (std::numeric_limits<Int>::min)();
395 r = m.template convert_to<Int>();
396 BOOST_CHECK_EQUAL(m, r);
401 template <class Real>
402 void test_integer_ops(const boost::mpl::int_<boost::multiprecision::number_kind_integer>&)
404 test_signed_integer_ops<Real>(boost::mpl::bool_<std::numeric_limits<Real>::is_signed>());
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);
416 BOOST_CHECK_EQUAL(a , 20 % 7);
418 c = (a + 2) % (a - 1);
419 BOOST_CHECK_EQUAL(c , 22 % 19);
422 BOOST_CHECK_EQUAL(a , 7 % 5);
427 BOOST_CHECK_EQUAL(a , 20 % 7);
428 #ifndef BOOST_NO_LONG_LONG
431 BOOST_CHECK_EQUAL(a , 20 % 7);
435 BOOST_CHECK_EQUAL(a , 21);
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);
444 BOOST_CHECK_EQUAL(a , 2000L << 20);
446 BOOST_CHECK_EQUAL(a , 2000);
448 BOOST_CHECK_EQUAL(a , 2000L << 20);
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);
457 #ifndef BOOST_NO_LONG_LONG
458 if(sizeof(long long) > sizeof(std::size_t))
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);
469 // Unless they fit within range:
472 BOOST_CHECK_EQUAL(a, (2000L << 20));
475 BOOST_CHECK_EQUAL(a, (2000L << 20));
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);
485 // Unless they fit within range:
487 BOOST_CHECK_EQUAL(Real(a << 20uLL) , (2000L << 20));
489 BOOST_CHECK_EQUAL(Real(a << 20LL) , (2000L << 20));
494 BOOST_CHECK_EQUAL(b , (20 << 20));
496 BOOST_CHECK_EQUAL(b , (20 >> 2));
498 BOOST_CHECK_EQUAL(b , (22 << 10));
500 BOOST_CHECK_EQUAL(b , (23 >> 3));
511 BOOST_CHECK_EQUAL(c , (i & j));
514 BOOST_CHECK_EQUAL(c , (i & j));
517 BOOST_CHECK_EQUAL(c , (i & (i + j)));
518 BOOST_CHECK_EQUAL((a & b) , (i & j));
521 BOOST_CHECK_EQUAL(a , (i & (j + k)));
524 BOOST_CHECK_EQUAL(a , (i & (j + k)));
527 BOOST_CHECK_EQUAL(c , (i&j&k));
530 BOOST_CHECK_EQUAL(c , (i & (i+j)));
532 BOOST_CHECK_EQUAL(c , (i & (j | 1)));
534 test_complement<Real>(a, b, c, typename is_twos_complement_integer<Real>::type());
540 BOOST_CHECK_EQUAL(c , (i | j));
543 BOOST_CHECK_EQUAL(c , (i | j));
546 BOOST_CHECK_EQUAL(c , (i | (i + j)));
547 BOOST_CHECK_EQUAL((a | b) , (i | j));
550 BOOST_CHECK_EQUAL(a , (i | (j + k)));
553 BOOST_CHECK_EQUAL(a , (i | (j + k)));
556 BOOST_CHECK_EQUAL(c , (i|j|k));
559 BOOST_CHECK_EQUAL(c , (i | (i+j)));
561 BOOST_CHECK_EQUAL(c , (i | (j | 1)));
567 BOOST_CHECK_EQUAL(c , (i ^ j));
570 BOOST_CHECK_EQUAL(c , (i ^ j));
573 BOOST_CHECK_EQUAL(c , (i ^ (i + j)));
574 BOOST_CHECK_EQUAL((a ^ b) , (i ^ j));
577 BOOST_CHECK_EQUAL(a , (i ^ (j + k)));
580 BOOST_CHECK_EQUAL(a , (i ^ (j + k)));
583 BOOST_CHECK_EQUAL(c , (i^j^k));
586 BOOST_CHECK_EQUAL(c , (i ^ (i+j)));
588 BOOST_CHECK_EQUAL(c , (i ^ (j | 1)));
594 // Non-member functions:
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));
610 // Conditionals involving 2 arg functions:
612 test_conditional(Real(gcd(a, b)), gcd(a, b));
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)
630 if(std::numeric_limits<Real>::is_specialized && (!std::numeric_limits<Real>::is_bounded || ((int)i * 17 < std::numeric_limits<Real>::digits)))
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));
638 BOOST_CHECK(!bit_test(Real(1) << (i * 17), i * 17 - 1));
641 BOOST_CHECK(bit_test(bit_set(zero, i * 17), i * 17));
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);
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);
674 // Conditionals involving 3 arg functions:
676 test_conditional(Real(powm(Real(3), Real(4), Real(13))), powm(Real(3), Real(4), Real(13)));
678 #ifndef BOOST_NO_EXCEPTIONS
680 // Things that are expected errors:
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);
687 // Extra tests added for full coverage:
692 BOOST_CHECK_EQUAL(c , (20 % 7));
694 BOOST_CHECK_EQUAL(c , (20 % 7));
696 BOOST_CHECK_EQUAL(c , (20 & 10));
698 BOOST_CHECK_EQUAL(c , (20 & 10));
699 c = (a + 0) & (b + 0);
700 BOOST_CHECK_EQUAL(c , (20 & 7));
702 BOOST_CHECK_EQUAL(c , (20 & 10));
704 BOOST_CHECK_EQUAL(c , (20 | 10));
705 c = (a + 0) | (b + 0);
706 BOOST_CHECK(c == (20 | 7))
708 BOOST_CHECK_EQUAL(c , (20 | 7));
710 BOOST_CHECK_EQUAL(c , (20 ^ 7));
712 BOOST_CHECK_EQUAL(c , (20 ^ 7));
713 c = (a + 0) ^ (b + 0);
714 BOOST_CHECK_EQUAL(c , (20 ^ 7));
716 BOOST_CHECK_EQUAL(c , (20 ^ 7));
720 // Round tripping of built in integers:
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>();
734 template <class Real, class T>
735 void test_float_funcs(const T&){}
737 template <class Real>
738 void test_float_funcs(const boost::mpl::true_&)
740 if(boost::multiprecision::is_interval_number<Real>::value)
743 // Test variable reuse in function calls, see https://svn.boost.org/trac/boost/ticket/8326
745 Real a(2), b(10), c, d;
747 BOOST_CHECK_EQUAL(a, 1024);
750 BOOST_CHECK_EQUAL(b, 1024);
753 BOOST_CHECK_EQUAL(a, 1024);
756 BOOST_CHECK_EQUAL(a, 2);
759 BOOST_CHECK_EQUAL(a, 2);
762 BOOST_CHECK_EQUAL(a, 2);
765 BOOST_CHECK_EQUAL(a, 3);
768 BOOST_CHECK_EQUAL(a, 2);
771 BOOST_CHECK_EQUAL(a, 2);
774 BOOST_CHECK_EQUAL(a, 4);
777 BOOST_CHECK_EQUAL(a, 0.5);
779 Real tol = std::numeric_limits<Real>::epsilon() * 3;
782 BOOST_CHECK_CLOSE_FRACTION(a, 2, tol);
785 BOOST_CHECK_CLOSE_FRACTION(a, Real(exp(Real(3))), tol);
788 BOOST_CHECK_CLOSE_FRACTION(a, Real(log(Real(3))), tol);
791 BOOST_CHECK_CLOSE_FRACTION(a, Real(log10(Real(3))), tol);
795 BOOST_CHECK_CLOSE_FRACTION(a, Real(sin(Real(0.5))), tol);
798 BOOST_CHECK_CLOSE_FRACTION(a, Real(cos(Real(0.5))), tol);
801 BOOST_CHECK_CLOSE_FRACTION(a, Real(tan(Real(0.5))), tol);
804 BOOST_CHECK_CLOSE_FRACTION(a, Real(asin(Real(0.5))), tol);
807 BOOST_CHECK_CLOSE_FRACTION(a, Real(acos(Real(0.5))), tol);
810 BOOST_CHECK_CLOSE_FRACTION(a, Real(atan(Real(0.5))), tol);
813 BOOST_CHECK_CLOSE_FRACTION(a, Real(sinh(Real(0.5))), tol);
816 BOOST_CHECK_CLOSE_FRACTION(a, Real(cosh(Real(0.5))), tol);
819 BOOST_CHECK_CLOSE_FRACTION(a, Real(tanh(Real(0.5))), tol);
820 // fmod, need to check all the sign permutations:
824 BOOST_CHECK_CLOSE_FRACTION(a, Real(fmod(Real(4), Real(2))), tol);
827 BOOST_CHECK_CLOSE_FRACTION(b, Real(fmod(Real(4), Real(2))), tol);
831 BOOST_CHECK_CLOSE_FRACTION(a, Real(fmod(-Real(4), Real(2))), tol);
834 BOOST_CHECK_CLOSE_FRACTION(b, Real(-fmod(Real(4), Real(2))), tol);
838 BOOST_CHECK_CLOSE_FRACTION(a, Real(fmod(Real(4), -Real(2))), tol);
841 BOOST_CHECK_CLOSE_FRACTION(b, Real(fmod(Real(4), -Real(2))), tol);
845 BOOST_CHECK_CLOSE_FRACTION(a, Real(fmod(-Real(4), -Real(2))), tol);
848 BOOST_CHECK_CLOSE_FRACTION(b, Real(fmod(-Real(4), -Real(2))), tol);
853 BOOST_CHECK_EQUAL(b + c, a);
854 BOOST_CHECK_EQUAL(b > 0, a > 0);
855 BOOST_CHECK_EQUAL(c > 0, a > 0);
858 BOOST_CHECK_EQUAL(b + c, a);
859 BOOST_CHECK_EQUAL(b > 0, a > 0);
860 BOOST_CHECK_EQUAL(c > 0, a > 0);
864 BOOST_CHECK_EQUAL(b + c, a);
865 BOOST_CHECK_EQUAL(b > 0, a > 0);
866 BOOST_CHECK_EQUAL(c > 0, a > 0);
871 BOOST_CHECK_EQUAL(b + c, a);
872 BOOST_CHECK_EQUAL(b > 0, a > 0);
873 BOOST_CHECK_EQUAL(c > 0, a > 0);
875 if(std::numeric_limits<Real>::has_infinity)
877 a = std::numeric_limits<Real>::infinity();
879 BOOST_CHECK_EQUAL(a, c);
880 BOOST_CHECK_EQUAL(b, 0);
881 a = -std::numeric_limits<Real>::infinity();
883 BOOST_CHECK_EQUAL(a, c);
884 BOOST_CHECK_EQUAL(b, 0);
886 if(std::numeric_limits<Real>::has_quiet_NaN)
888 a = std::numeric_limits<Real>::quiet_NaN();
890 BOOST_CHECK((boost::math::isnan)(b));
891 BOOST_CHECK((boost::math::isnan)(c));
897 BOOST_CHECK_CLOSE_FRACTION(a, Real(atan2(Real(4), Real(2))), tol);
900 BOOST_CHECK_CLOSE_FRACTION(b, Real(atan2(Real(4), Real(2))), tol);
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);
921 // Default construct, for consistency with native floats, default constructed values are zero:
923 BOOST_CHECK_EQUAL(zero, 0);
926 template <class T, class U>
927 void compare_NaNs(const T& a, const U& b)
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);
936 // Again where LHS may be an expression template:
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);
945 // Again where RHS may be an expression template:
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);
954 // Again where LHS and RHS may be an expression templates:
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);
964 template <class Real, class T>
965 void test_float_ops(const T&){}
967 template <class Real>
968 void test_float_ops(const boost::mpl::int_<boost::multiprecision::number_kind_floating_point>&)
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);
981 // ldexp and frexp, these pretty much have to be implemented by each backend:
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);
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);
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);
1000 r = frexp(v, &exp2);
1001 BOOST_CHECK_EQUAL(r , 0.5);
1002 BOOST_CHECK_EQUAL(exp2 , 10);
1003 BOOST_CHECK_EQUAL(v , 512);
1005 r = frexp(v, &exp2);
1006 BOOST_CHECK_EQUAL(r , 0.5);
1007 BOOST_CHECK_EQUAL(exp2 , -8);
1009 // scalbn and logb, these are the same as ldexp and frexp unless the radix is
1010 // something other than 2:
1012 if(std::numeric_limits<Real>::is_specialized && std::numeric_limits<Real>::radix)
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));
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));
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));
1032 // pow and exponent:
1036 BOOST_CHECK_EQUAL(r , 1);
1038 BOOST_CHECK_EQUAL(r , 3.25);
1040 BOOST_CHECK_EQUAL(r , boost::math::pow<2>(3.25));
1042 BOOST_CHECK_EQUAL(r , boost::math::pow<3>(3.25));
1044 BOOST_CHECK_EQUAL(r , boost::math::pow<4>(3.25));
1046 BOOST_CHECK_EQUAL(r , boost::math::pow<5>(3.25));
1048 BOOST_CHECK_EQUAL(r , boost::math::pow<6>(3.25));
1050 BOOST_CHECK_EQUAL(r , boost::math::pow<25>(Real(3.25)));
1052 #ifndef BOOST_NO_EXCEPTIONS
1054 // Things that are expected errors:
1056 BOOST_CHECK_THROW(Real("3.14L"), std::runtime_error);
1057 if(std::numeric_limits<Real>::is_specialized)
1059 if(std::numeric_limits<Real>::has_infinity)
1061 BOOST_CHECK((boost::math::isinf)(Real(20) / 0u));
1065 BOOST_CHECK_THROW(Real(Real(20) / 0u), std::overflow_error);
1070 // Comparisons of NaN's should always fail:
1072 if(std::numeric_limits<Real>::has_quiet_NaN)
1074 r = v = std::numeric_limits<Real>::quiet_NaN();
1081 // Conmpare NaN to int:
1086 // Compare to floats:
1088 compare_NaNs(v, 0.5);
1089 compare_NaNs(0.5, v);
1090 if(std::numeric_limits<double>::has_quiet_NaN)
1092 compare_NaNs(r, std::numeric_limits<double>::quiet_NaN());
1093 compare_NaNs(std::numeric_limits<double>::quiet_NaN(), r);
1098 // Operations involving NaN's as one argument:
1100 if(std::numeric_limits<Real>::has_quiet_NaN)
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));
1113 BOOST_CHECK((boost::math::isnan)(t += r));
1115 BOOST_CHECK((boost::math::isnan)(t += v));
1117 BOOST_CHECK((boost::math::isnan)(t -= v));
1119 BOOST_CHECK((boost::math::isnan)(t -= r));
1121 BOOST_CHECK((boost::math::isnan)(t *= v));
1123 BOOST_CHECK((boost::math::isnan)(t *= r));
1125 BOOST_CHECK((boost::math::isnan)(t /= v));
1127 BOOST_CHECK((boost::math::isnan)(t /= r));
1130 // Operations involving infinities as one argument:
1132 if(std::numeric_limits<Real>::has_infinity)
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);
1146 BOOST_CHECK((boost::math::isinf)(t += r));
1148 BOOST_CHECK((boost::math::isinf)(t += v));
1150 BOOST_CHECK((boost::math::isinf)(t -= v));
1152 BOOST_CHECK((boost::math::isinf)(t -= r));
1154 BOOST_CHECK(t -= r < 0);
1156 BOOST_CHECK((boost::math::isinf)(t *= v));
1158 BOOST_CHECK((boost::math::isinf)(t *= r));
1160 BOOST_CHECK((boost::math::isinf)(t /= v));
1162 BOOST_CHECK((t /= r) == 0);
1165 // Operations that should produce NaN as a result:
1167 if(std::numeric_limits<Real>::has_quiet_NaN)
1171 BOOST_CHECK((boost::math::isnan)(t));
1173 BOOST_CHECK((boost::math::isnan)(v));
1175 BOOST_CHECK((boost::math::isnan)(v));
1176 if(std::numeric_limits<Real>::has_infinity)
1179 r = std::numeric_limits<Real>::infinity();
1181 if(!boost::multiprecision::is_interval_number<Real>::value)
1183 BOOST_CHECK((boost::math::isnan)(t));
1185 BOOST_CHECK((boost::math::isnan)(t));
1189 BOOST_CHECK((boost::math::isnan)(t));
1193 test_float_funcs<Real>(boost::mpl::bool_<std::numeric_limits<Real>::is_specialized>());
1197 struct lexical_cast_target_type
1199 typedef typename boost::mpl::if_<
1200 boost::is_signed<T>,
1202 typename boost::mpl::if_<
1203 boost::is_unsigned<T>,
1210 template <class Real, class Num>
1211 void test_negative_mixed_minmax(boost::mpl::true_ const&)
1213 if(!std::numeric_limits<Real>::is_bounded || (std::numeric_limits<Real>::digits >= std::numeric_limits<Num>::digits))
1215 Real mx1((std::numeric_limits<Num>::max)() - 1);
1217 Real mx2((std::numeric_limits<Num>::max)());
1218 BOOST_CHECK_EQUAL(mx1, mx2);
1219 mx1 = (std::numeric_limits<Num>::max)() - 1;
1221 mx2 = (std::numeric_limits<Num>::max)();
1222 BOOST_CHECK_EQUAL(mx1, mx2);
1224 if(!std::numeric_limits<Real>::is_bounded || (std::numeric_limits<Real>::digits > std::numeric_limits<Num>::digits))
1226 Real mx3((std::numeric_limits<Num>::min)() + 1);
1228 Real mx4((std::numeric_limits<Num>::min)());
1229 BOOST_CHECK_EQUAL(mx3, mx4);
1230 mx3 = (std::numeric_limits<Num>::min)() + 1;
1232 mx4 = (std::numeric_limits<Num>::min)();
1233 BOOST_CHECK_EQUAL(mx3, mx4);
1237 template <class Real, class Num>
1238 void test_negative_mixed_minmax(boost::mpl::false_ const&)
1242 template <class Real, class Num>
1243 void test_negative_mixed(boost::mpl::true_ const&)
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,
1251 typedef typename boost::mpl::if_<
1252 boost::is_convertible<Num, 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));
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>());
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);
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);
1301 #if defined(TEST_MPFR)
1302 Num tol = 10 * std::numeric_limits<Num>::epsilon();
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)
1311 BOOST_CHECK_CLOSE(n1, checked_lexical_cast<target_type>(Real(n1).str(digits_to_print, f)), tol);
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);
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));
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));
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));
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));
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));
1352 // Extra cases for full coverage:
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));
1371 BOOST_CHECK_EQUAL(c , 10);
1373 BOOST_CHECK_EQUAL(c , 10);
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);
1380 BOOST_CHECK_EQUAL(c , -50);
1382 c = -(a + b) + static_cast<cast_type>(n4);
1383 BOOST_CHECK_EQUAL(c , -50+4);
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);
1394 BOOST_CHECK_EQUAL(c , 50);
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));
1414 BOOST_CHECK_EQUAL(c , 20 * -30);
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);
1422 BOOST_CHECK(-50 + 20);
1423 c = static_cast<cast_type>(n4) - (a + b);
1424 BOOST_CHECK_EQUAL(c , 0);
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);
1436 BOOST_CHECK_EQUAL(c , -1);
1438 BOOST_CHECK_EQUAL(c , -1);
1441 BOOST_CHECK_EQUAL(c , 20 / -2);
1443 BOOST_CHECK_EQUAL(c , 20 / -2);
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);
1459 a = static_cast<cast_type>(n1);
1460 b = static_cast<cast_type>(n2);
1461 c = static_cast<cast_type>(n3);
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);
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);
1496 BOOST_CHECK_EQUAL(d , -20 - -3 * -4);
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);
1516 BOOST_CHECK_EQUAL(d , -3 * -4 - -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);
1529 // Conversion from min and max values:
1531 test_negative_mixed_minmax<Real, Num>(boost::mpl::bool_<std::numeric_limits<Real>::is_integer && std::numeric_limits<Num>::is_integer>());
1534 template <class Real, class Num>
1535 void test_negative_mixed(boost::mpl::false_ const&)
1539 template <class Real, class Num>
1540 void test_mixed(const boost::mpl::false_&)
1544 template <class Real>
1545 inline bool check_is_nan(const Real& val, const boost::mpl::true_&)
1547 return (boost::math::isnan)(val);
1549 template <class Real>
1550 inline bool check_is_nan(const Real&, const boost::mpl::false_&)
1554 template <class Real>
1555 inline Real negate_value(const Real& val, const boost::mpl::true_&)
1559 template <class Real>
1560 inline Real negate_value(const Real& val, const boost::mpl::false_&)
1565 template <class Real, class Num>
1566 void test_mixed(const boost::mpl::true_&)
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,
1574 typedef typename boost::mpl::if_<
1575 boost::is_convertible<Num, Real>,
1578 >::type simple_cast_type;
1580 if(std::numeric_limits<Real>::is_specialized && std::numeric_limits<Real>::is_bounded && std::numeric_limits<Real>::digits < std::numeric_limits<Num>::digits)
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));
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>());
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);
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);
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();
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)
1638 BOOST_CHECK_CLOSE(n1, checked_lexical_cast<target_type>(Real(n1).str(digits_to_print, f)), tol);
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);
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));
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));
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));
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));
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));
1679 // special cases for full coverage:
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));
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;
1694 test_negative_mixed<Real, Num>(signed_tag());
1699 Real a(n1), b(n2), c(n3), d;
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);
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);
1734 BOOST_CHECK_EQUAL(d , 20 - 3 * 4);
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);
1754 BOOST_CHECK_EQUAL(d , 3 * 4 - 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);
1767 if(std::numeric_limits<Real>::has_infinity && std::numeric_limits<Num>::has_infinity)
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>()));
1774 if(std::numeric_limits<Real>::has_quiet_NaN && std::numeric_limits<Num>::has_quiet_NaN)
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>()));
1783 template <class Real>
1784 void test_members(Real)
1787 // Test sign and zero functions:
1791 BOOST_CHECK(a.sign() > 0);
1792 BOOST_CHECK(!a.is_zero());
1793 if(std::numeric_limits<Real>::is_signed)
1796 BOOST_CHECK(a.sign() < 0);
1797 BOOST_CHECK(!a.is_zero());
1800 BOOST_CHECK_EQUAL(a.sign() , 0);
1801 BOOST_CHECK(a.is_zero());
1806 BOOST_CHECK_EQUAL(a , 30);
1807 BOOST_CHECK_EQUAL(b , 20);
1810 template <class Real>
1811 void test_members(boost::rational<Real>)
1815 template <class Real>
1816 void test_signed_ops(const boost::mpl::true_&)
1823 BOOST_CHECK_EQUAL(-a , -8);
1826 BOOST_CHECK_EQUAL(ac , 8 - 64);
1829 BOOST_CHECK_EQUAL(ac , -64);
1832 BOOST_CHECK_EQUAL(ac , 16 - 64);
1834 BOOST_CHECK_EQUAL(ac , -8);
1837 BOOST_CHECK_EQUAL(ac , 16);
1840 BOOST_CHECK_EQUAL(ac , 0);
1843 BOOST_CHECK_EQUAL(ac , -8);
1846 BOOST_CHECK_EQUAL(ac , -64);
1848 BOOST_CHECK_EQUAL(ac , 8 - 64);
1850 BOOST_CHECK_EQUAL(ac , -8+64);
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);
1857 template <class Real>
1858 void test_signed_ops(const boost::mpl::false_&)
1862 template <class Real>
1863 void test_basic_conditionals(Real a, Real b)
1867 BOOST_ERROR("Unexpected non-zero result");
1872 BOOST_ERROR("Unexpected zero result");
1877 BOOST_ERROR("Unexpected zero result");
1882 BOOST_ERROR("Unexpected non-zero result");
1886 BOOST_ERROR("Unexpected zero result");
1890 BOOST_ERROR("Unexpected zero result");
1895 BOOST_ERROR("Unexpected zero result");
1899 BOOST_ERROR("Unexpected non-zero result");
1903 template <class Real>
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);
1921 test_mixed<Real, float>(tag);
1922 test_mixed<Real, double>(tag);
1923 test_mixed<Real, long double>(tag);
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;
1928 test_mixed<Real, related_type>(tag2);
1932 // Integer only functions:
1934 test_integer_ops<Real>(typename boost::multiprecision::number_category<Real>::type());
1936 // Real number only functions:
1938 test_float_ops<Real>(typename boost::multiprecision::number_category<Real>::type());
1940 // Test basic arithmetic:
1946 BOOST_CHECK_EQUAL(a + b , 72);
1948 BOOST_CHECK_EQUAL(a , 72);
1949 BOOST_CHECK_EQUAL(a - b , 8);
1951 BOOST_CHECK_EQUAL(a , 8);
1952 BOOST_CHECK_EQUAL(a * b , 8*64L);
1954 BOOST_CHECK_EQUAL(a , 8*64L);
1955 BOOST_CHECK_EQUAL(a / b , 8);
1957 BOOST_CHECK_EQUAL(a , 8);
1959 BOOST_CHECK_EQUAL(ac , a);
1961 BOOST_CHECK_EQUAL(ac , 8*500L);
1964 BOOST_CHECK_EQUAL(ac , 8*500L+64+500);
1967 BOOST_CHECK_EQUAL(ac , 8+64+500);
1969 BOOST_CHECK_EQUAL(ac , 8+64+500-64+500);
1972 BOOST_CHECK_EQUAL(ac , -8+64+500);
1975 BOOST_CHECK_EQUAL(ac , 8*64);
1978 BOOST_CHECK_EQUAL(ac , 8*8*64);
1981 BOOST_CHECK_EQUAL(ac , 64/8);
1984 BOOST_CHECK_EQUAL(ac , 64 / (64/8));
1987 BOOST_CHECK_EQUAL(ac , 64 * 2);
1990 BOOST_CHECK_EQUAL(ac , 0);
1993 BOOST_CHECK_EQUAL(ac , 64 * (16));
1996 BOOST_CHECK_EQUAL(ac , 64 / 8);
1999 BOOST_CHECK_EQUAL(ac , 8 + 64);
2002 BOOST_CHECK_EQUAL(ac , 16);
2005 BOOST_CHECK_EQUAL(ac , 0);
2008 BOOST_CHECK_EQUAL(ac , 80);
2011 BOOST_CHECK_EQUAL(ac , 80);
2013 BOOST_CHECK_EQUAL(ac , 8);
2016 BOOST_CHECK_EQUAL(ac , 8*8);
2020 BOOST_CHECK_EQUAL(ac , 16);
2023 BOOST_CHECK_EQUAL(ac , 8 + 64-8);
2026 BOOST_CHECK_EQUAL(ac , 8 + 64 * 500);
2030 BOOST_CHECK_EQUAL(ac , 0);
2032 if(std::numeric_limits<Real>::is_signed || is_twos_complement_integer<Real>::value)
2036 BOOST_CHECK_EQUAL(ac , 8 - (500-64));
2039 BOOST_CHECK_EQUAL(ac , 8 - 500*64);
2043 BOOST_CHECK_EQUAL(ac , 8 + 8 * 64);
2044 if(std::numeric_limits<Real>::is_signed || is_twos_complement_integer<Real>::value)
2048 BOOST_CHECK_EQUAL(ac , 8 - 8 * 64);
2052 BOOST_CHECK_EQUAL(ac , 64 * 8);
2055 BOOST_CHECK_EQUAL(ac , 8 * 64 * 500);
2058 BOOST_CHECK_EQUAL(ac , 8 * 64 / 8);
2061 BOOST_CHECK_EQUAL(ac , 8 * (64 + 500));
2064 BOOST_CHECK_EQUAL(ac , 8);
2067 BOOST_CHECK_EQUAL(ac , 64 / (64/8));
2070 BOOST_CHECK_EQUAL(ac , 8);
2072 // simple tests with immediate values, these calls can be optimised in many backends:
2075 BOOST_CHECK_EQUAL(ac , 72);
2077 BOOST_CHECK_EQUAL(ac , 72);
2079 BOOST_CHECK_EQUAL(ac , 72);
2081 BOOST_CHECK_EQUAL(ac , 72);
2084 BOOST_CHECK_EQUAL(ac , b / a);
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);
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);
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);
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);
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);
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);
2157 // Use in Boolean context:
2161 test_basic_conditionals(a, b);
2165 std::stringstream ss;
2170 BOOST_CHECK_EQUAL(a , c);
2174 BOOST_CHECK_EQUAL(c , 22);
2175 BOOST_CHECK_EQUAL(c , a + b);
2177 // More cases for complete code coverage:
2182 BOOST_CHECK_EQUAL(a , 30);
2183 BOOST_CHECK_EQUAL(b , 20);
2187 BOOST_CHECK_EQUAL(a , 30);
2188 BOOST_CHECK_EQUAL(b , 20);
2192 BOOST_CHECK_EQUAL(a , 20 + 30 * 2);
2195 BOOST_CHECK_EQUAL(a , 100 - 30 * 2);
2198 BOOST_CHECK_EQUAL(a , 20 * (32));
2201 BOOST_CHECK_EQUAL(a , 20 * (32));
2205 BOOST_CHECK_EQUAL(a , 45);
2209 BOOST_CHECK_EQUAL(c , 20 * 30 + 22);
2211 BOOST_CHECK_EQUAL(c , 20 * 30 + 22);
2214 BOOST_CHECK_EQUAL(ac , 20 + 30 * 10);
2216 BOOST_CHECK_EQUAL(ac , 20 + 30 * 10);
2218 BOOST_CHECK_EQUAL(a , 20 + 30 * 10);
2221 BOOST_CHECK_EQUAL(b , 20 + 30 * 10);
2224 BOOST_CHECK_EQUAL(c , 20 + 30 * 10);
2227 BOOST_CHECK_EQUAL(c , 20 + 30 / 10);
2230 // Test conditionals:
2233 test_conditional(a, +a);
2234 test_conditional(a, (a + 0));
2236 test_signed_ops<Real>(boost::mpl::bool_<std::numeric_limits<Real>::is_signed>());
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);
2252 BOOST_CHECK_EQUAL(c, 20);
2253 // Destructor of "a" checks destruction of moved-from-object...
2254 Real m3(static_cast<Real&&>(a));
2257 // min and max overloads:
2259 #if !defined(min) && !defined(max)
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);
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);
2292 // Bug cases, self assignment first:
2296 BOOST_CHECK_EQUAL(a, 20);
2300 BOOST_CHECK_EQUAL(a, 8);
2303 BOOST_CHECK_EQUAL(a, 6);
2306 BOOST_CHECK_EQUAL(a, 2);
2309 BOOST_CHECK_EQUAL(a, 2);
2312 BOOST_CHECK_EQUAL(a, 2);
2315 BOOST_CHECK_EQUAL(a, 6);
2318 BOOST_CHECK_EQUAL(a, 8);