/////////////////////////////////////////////////////////////// // Copyright 2011 John Maddock. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_ #include #include #include #if !defined(TEST_MPF50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) # define TEST_MPF50 # define TEST_MPF # define TEST_BACKEND # define TEST_MPZ #endif template void test_integer_ops(const boost::mpl::false_&){} template void test_integer_ops(const boost::mpl::true_&) { Real a(20); Real b(7); BOOST_TEST(a % b == 20 % 7); BOOST_TEST(a % 7 == 20 % 7); BOOST_TEST(a % 7u == 20 % 7); BOOST_TEST(-a % b == -20 % 7); BOOST_TEST(-a % -b == -20 % -7); BOOST_TEST(a % -b == 20 % -7); BOOST_TEST(-a % 7 == -20 % 7); BOOST_TEST(-a % -7 == -20 % -7); BOOST_TEST(a % -7 == 20 % -7); BOOST_TEST(-a % 7u == -20 % 7); a = 20; a %= b; BOOST_TEST(a == 20 % 7); a = -20; a %= b; BOOST_TEST(a == -20 % 7); a = 20; a %= -b; BOOST_TEST(a == 20 % -7); a = -20; a %= -b; BOOST_TEST(a == -20 % -7); a = 20; a %= 7; BOOST_TEST(a == 20 % 7); a = -20; a %= 7; BOOST_TEST(a == -20 % 7); a = 20; a %= -7; BOOST_TEST(a == 20 % -7); a = -20; a %= -7; BOOST_TEST(a == -20 % -7); } template void test_real_ops(const boost::mpl::false_&){} template void test_real_ops(const boost::mpl::true_&) { std::cout << "Root2 = " << sqrt(Real(2)) << std::endl; BOOST_TEST(abs(Real(2)) == 2); BOOST_TEST(abs(Real(-2)) == 2); BOOST_TEST(fabs(Real(2)) == 2); BOOST_TEST(fabs(Real(-2)) == 2); BOOST_TEST(floor(Real(5) / 2) == 2); BOOST_TEST(ceil(Real(5) / 2) == 3); BOOST_TEST(floor(Real(-5) / 2) == -3); BOOST_TEST(ceil(Real(-5) / 2) == -2); BOOST_TEST(trunc(Real(5) / 2) == 2); BOOST_TEST(trunc(Real(-5) / 2) == -2); } template void test_negative_mixed(boost::mpl::true_ const&) { std::cout << "Testing mixed arithmetic with type: " << typeid(Real).name() << " and " << typeid(Num).name() << std::endl; Num n1 = -static_cast(1uLL << (std::numeric_limits::digits - 1)); Num n2 = -1; Num n3 = 0; Num n4 = -20; Num n5 = -8; // Default construct: BOOST_TEST(Real(n1) == n1); BOOST_TEST(Real(n2) == n2); BOOST_TEST(Real(n3) == n3); BOOST_TEST(Real(n4) == n4); BOOST_TEST(n1 == Real(n1)); BOOST_TEST(n2 == Real(n2)); BOOST_TEST(n3 == Real(n3)); BOOST_TEST(n4 == Real(n4)); BOOST_TEST(n1 == boost::lexical_cast(Real(n1))); BOOST_TEST(n2 == boost::lexical_cast(Real(n2))); BOOST_TEST(n3 == boost::lexical_cast(Real(n3))); BOOST_TEST(n4 == boost::lexical_cast(Real(n4))); // Assignment: Real r(0); BOOST_TEST(r != n1); r = n1; BOOST_TEST(r == n1); r = n2; BOOST_TEST(r == n2); r = n3; BOOST_TEST(r == n3); r = n4; BOOST_TEST(r == n4); // Addition: r = n2; BOOST_TEST(r + n4 == n2 + n4); BOOST_TEST(Real(r + n4) == n2 + n4); r += n4; BOOST_TEST(r == n2 + n4); // subtraction: r = n4; BOOST_TEST(r - n5 == n4 - n5); BOOST_TEST(Real(r - n5) == n4 - n5); r -= n5; BOOST_TEST(r == n4 - n5); // Multiplication: r = n2; BOOST_TEST(r * n4 == n2 * n4); BOOST_TEST(Real(r * n4) == n2 * n4); r *= n4; BOOST_TEST(r == n2 * n4); // Division: r = n1; BOOST_TEST(r / n5 == n1 / n5); BOOST_TEST(Real(r / n5) == n1 / n5); r /= n5; BOOST_TEST(r == n1 / n5); } template void test_negative_mixed(boost::mpl::false_ const&) { } template void test_mixed() { std::cout << "Testing mixed arithmetic with type: " << typeid(Real).name() << " and " << typeid(Num).name() << std::endl; Num n1 = static_cast(1uLL << (std::numeric_limits::digits - 1)); Num n2 = 1; Num n3 = 0; Num n4 = 20; Num n5 = 8; // Default construct: BOOST_TEST(Real(n1) == n1); BOOST_TEST(Real(n2) == n2); BOOST_TEST(Real(n3) == n3); BOOST_TEST(Real(n4) == n4); BOOST_TEST(n1 == Real(n1)); BOOST_TEST(n2 == Real(n2)); BOOST_TEST(n3 == Real(n3)); BOOST_TEST(n4 == Real(n4)); BOOST_TEST(n1 == boost::lexical_cast(Real(n1))); BOOST_TEST(n2 == boost::lexical_cast(Real(n2))); BOOST_TEST(n3 == boost::lexical_cast(Real(n3))); BOOST_TEST(n4 == boost::lexical_cast(Real(n4))); // Assignment: Real r(0); BOOST_TEST(r != n1); r = n1; BOOST_TEST(r == n1); r = n2; BOOST_TEST(r == n2); r = n3; BOOST_TEST(r == n3); r = n4; BOOST_TEST(r == n4); // Addition: r = n2; BOOST_TEST(r + n4 == n2 + n4); BOOST_TEST(Real(r + n4) == n2 + n4); r += n4; BOOST_TEST(r == n2 + n4); // subtraction: r = n4; BOOST_TEST(r - n5 == n4 - n5); BOOST_TEST(Real(r - n5) == n4 - n5); r -= n5; BOOST_TEST(r == n4 - n5); // Multiplication: r = n2; BOOST_TEST(r * n4 == n2 * n4); BOOST_TEST(Real(r * n4) == n2 * n4); r *= n4; BOOST_TEST(r == n2 * n4); // Division: r = n1; BOOST_TEST(r / n5 == n1 / n5); BOOST_TEST(Real(r / n5) == n1 / n5); r /= n5; BOOST_TEST(r == n1 / n5); test_negative_mixed(boost::mpl::bool_::is_signed>()); } template void test() { test_mixed(); test_mixed(); test_mixed(); test_mixed(); test_mixed(); test_mixed(); test_mixed(); test_mixed(); test_mixed(); #ifdef BOOST_HAS_LONG_LONG test_mixed(); test_mixed(); #endif test_mixed(); test_mixed(); test_mixed(); // // Integer only functions: // test_integer_ops(boost::math::is_extended_integer()); // // Real number only functions: // test_real_ops(boost::mpl::bool_::value >()); // // Test basic arithmetic: // Real a(8); Real b(64); Real c(500); Real d(1024); BOOST_TEST(a + b == 72); a += b; BOOST_TEST(a == 72); BOOST_TEST(a - b == 8); a -= b; BOOST_TEST(a == 8); BOOST_TEST(a * b == 8*64L); a *= b; BOOST_TEST(a == 8*64L); BOOST_TEST(a / b == 8); a /= b; BOOST_TEST(a == 8); Real ac(a); BOOST_TEST(ac == a); BOOST_TEST(-a == -8); ac = a * c; BOOST_TEST(ac == 8*500L); ac = ac + b + c; BOOST_TEST(ac == 8*500L+64+500); ac = a; ac = b + c + ac; BOOST_TEST(ac == 8+64+500); ac = ac - b + c; BOOST_TEST(ac == 8+64+500-64+500); ac = a; ac = b + c - ac; BOOST_TEST(ac == -8+64+500); ac = a; ac = ac * b; BOOST_TEST(ac == 8*64); ac = a; ac *= b * ac; BOOST_TEST(ac == 8*8*64); ac = b; ac = ac / a; BOOST_TEST(ac == 64/8); ac = b; ac /= ac / a; BOOST_TEST(ac == 64 / (64/8)); ac = a; ac = b + ac * a; BOOST_TEST(ac == 64 * 2); ac = a; ac = b - ac * a; BOOST_TEST(ac == 0); ac = a; ac = b * (ac + a); BOOST_TEST(ac == 64 * (16)); ac = a; ac = b / (ac * 1); BOOST_TEST(ac == 64 / 8); ac = a; ac = ac + b; BOOST_TEST(ac == 8 + 64); ac = a; ac = a + ac; BOOST_TEST(ac == 16); ac = a; ac = ac - b; BOOST_TEST(ac == 8 - 64); ac = a; ac = a - ac; BOOST_TEST(ac == 0); ac = a; ac += a + b; BOOST_TEST(ac == 80); ac = a; ac += b + a; BOOST_TEST(ac == 80); ac = a; ac -= a + b; BOOST_TEST(ac == -64); ac = a; ac -= b - a; BOOST_TEST(ac == 16 - 64); ac = +a; BOOST_TEST(ac == 8); ac = -a; BOOST_TEST(ac == -8); ac = 8; ac = a * ac; BOOST_TEST(ac == 8*8); ac = a; ac = ac + "8"; BOOST_TEST(ac == 16); ac = a; ac += +a; BOOST_TEST(ac == 16); ac = a; ac += -a; BOOST_TEST(ac == 0); ac = a; ac += b - a; BOOST_TEST(ac == 8 + 64-8); ac = a; ac += b*c; BOOST_TEST(ac == 8 + 64 * 500); ac = a; ac = ac - "8"; BOOST_TEST(ac == 0); ac = a; ac -= +a; BOOST_TEST(ac == 0); ac = a; ac -= -a; BOOST_TEST(ac == 16); ac = a; ac -= c - b; BOOST_TEST(ac == 8 - (500-64)); ac = a; ac -= b*c; BOOST_TEST(ac == 8 - 500*64); ac = a; ac += ac * b; BOOST_TEST(ac == 8 + 8 * 64); ac = a; ac -= ac * b; BOOST_TEST(ac == 8 - 8 * 64); ac = a * "8"; BOOST_TEST(ac == 64); ac *= +a; BOOST_TEST(ac == 64 * 8); ac = a; ac *= -a; BOOST_TEST(ac == -64); ac = a; ac *= b * c; BOOST_TEST(ac == 8 * 64 * 500); ac = a; ac *= b / a; BOOST_TEST(ac == 8 * 64 / 8); ac = a; ac *= b + c; BOOST_TEST(ac == 8 * (64 + 500)); ac = b / "8"; BOOST_TEST(ac == 8); ac = b; ac /= +a; BOOST_TEST(ac == 8); ac = b; ac /= -a; BOOST_TEST(ac == -8); ac = b; ac /= b / a; BOOST_TEST(ac == 64 / (64/8)); ac = b; ac /= a + Real(0); BOOST_TEST(ac == 8); ac = a + std::string("8"); BOOST_TEST(ac == 16); // // Comparisons: // BOOST_TEST((a == b) == false); BOOST_TEST((a != b) == true); BOOST_TEST((a <= b) == true); BOOST_TEST((a < b) == true); BOOST_TEST((a >= b) == false); BOOST_TEST((a > b) == false); BOOST_TEST((a+b == b) == false); BOOST_TEST((a+b != b) == true); BOOST_TEST((a+b >= b) == true); BOOST_TEST((a+b > b) == true); BOOST_TEST((a+b <= b) == false); BOOST_TEST((a+b < b) == false); BOOST_TEST((a == b+a) == false); BOOST_TEST((a != b+a) == true); BOOST_TEST((a <= b+a) == true); BOOST_TEST((a < b+a) == true); BOOST_TEST((a >= b+a) == false); BOOST_TEST((a > b+a) == false); BOOST_TEST((a+b == b+a) == true); BOOST_TEST((a+b != b+a) == false); BOOST_TEST((a+b <= b+a) == true); BOOST_TEST((a+b < b+a) == false); BOOST_TEST((a+b >= b+a) == true); BOOST_TEST((a+b > b+a) == false); BOOST_TEST((8 == b+a) == false); BOOST_TEST((8 != b+a) == true); BOOST_TEST((8 <= b+a) == true); BOOST_TEST((8 < b+a) == true); BOOST_TEST((8 >= b+a) == false); BOOST_TEST((8 > b+a) == false); BOOST_TEST((800 == b+a) == false); BOOST_TEST((800 != b+a) == true); BOOST_TEST((800 >= b+a) == true); BOOST_TEST((800 > b+a) == true); BOOST_TEST((800 <= b+a) == false); BOOST_TEST((800 < b+a) == false); BOOST_TEST((72 == b+a) == true); BOOST_TEST((72 != b+a) == false); BOOST_TEST((72 <= b+a) == true); BOOST_TEST((72 < b+a) == false); BOOST_TEST((72 >= b+a) == true); BOOST_TEST((72 > b+a) == false); } int main() { #ifdef TEST_BACKEND test >(); #endif #ifdef TEST_MPF50 test(); #endif #ifdef TEST_MPF boost::math::mpf_real::default_precision(1000); boost::math::mpf_real r; r.precision(50); BOOST_TEST(r.precision() >= 50); BOOST_TEST(boost::math::mpf_real::default_precision() == 1000); test(); #endif #ifdef TEST_MPZ test(); #endif return boost::report_errors(); }