mirror of
https://github.com/boostorg/multiprecision.git
synced 2026-02-12 12:12:26 +00:00
444 lines
10 KiB
C++
444 lines
10 KiB
C++
///////////////////////////////////////////////////////////////
|
|
// 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 <boost/detail/lightweight_test.hpp>
|
|
#include <boost/math/concepts/big_number_architypes.hpp>
|
|
#include <boost/math/big_number/gmp.hpp>
|
|
|
|
#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 <class Real>
|
|
void test_integer_ops(const boost::mpl::false_&){}
|
|
|
|
template <class Real>
|
|
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 <class Real, class Num>
|
|
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<Num>(1uLL << (std::numeric_limits<Num>::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<long double>(Real(n1)));
|
|
BOOST_TEST(n2 == boost::lexical_cast<long double>(Real(n2)));
|
|
BOOST_TEST(n3 == boost::lexical_cast<long double>(Real(n3)));
|
|
BOOST_TEST(n4 == boost::lexical_cast<long double>(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 <class Real, class Num>
|
|
void test_negative_mixed(boost::mpl::false_ const&)
|
|
{
|
|
}
|
|
|
|
template <class Real, class Num>
|
|
void test_mixed()
|
|
{
|
|
std::cout << "Testing mixed arithmetic with type: " << typeid(Real).name() << " and " << typeid(Num).name() << std::endl;
|
|
Num n1 = static_cast<Num>(1uLL << (std::numeric_limits<Num>::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<long double>(Real(n1)));
|
|
BOOST_TEST(n2 == boost::lexical_cast<long double>(Real(n2)));
|
|
BOOST_TEST(n3 == boost::lexical_cast<long double>(Real(n3)));
|
|
BOOST_TEST(n4 == boost::lexical_cast<long double>(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<Real, Num>(boost::mpl::bool_<std::numeric_limits<Num>::is_signed>());
|
|
}
|
|
|
|
template <class Real>
|
|
void test()
|
|
{
|
|
test_mixed<Real, unsigned char>();
|
|
test_mixed<Real, signed char>();
|
|
test_mixed<Real, char>();
|
|
test_mixed<Real, short>();
|
|
test_mixed<Real, unsigned short>();
|
|
test_mixed<Real, int>();
|
|
test_mixed<Real, unsigned int>();
|
|
test_mixed<Real, long>();
|
|
test_mixed<Real, unsigned long>();
|
|
#ifdef BOOST_HAS_LONG_LONG
|
|
test_mixed<Real, long long>();
|
|
test_mixed<Real, unsigned long long>();
|
|
#endif
|
|
test_mixed<Real, float>();
|
|
test_mixed<Real, double>();
|
|
test_mixed<Real, long double>();
|
|
//
|
|
// Integer only functions:
|
|
//
|
|
test_integer_ops<Real>(boost::math::is_extended_integer<Real>());
|
|
//
|
|
// 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<boost::math::big_number<boost::math::concepts::big_number_backend_real_architype> >();
|
|
#endif
|
|
#ifdef TEST_MPF50
|
|
test<boost::math::mpf_real_50>();
|
|
#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<boost::math::mpf_real>();
|
|
#endif
|
|
#ifdef TEST_MPZ
|
|
test<boost::math::mpz_int>();
|
|
#endif
|
|
return boost::report_errors();
|
|
}
|