123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699 |
- // Copyright John Maddock 2013.
- // Use, modification and distribution are subject to the
- // Boost Software License, Version 1.0.
- // (See accompanying file LICENSE_1_0.txt
- // or copy at http://www.boost.org/LICENSE_1_0.txt)
- #ifdef _MSC_VER
- #define _SCL_SECURE_NO_WARNINGS
- #endif
- #include <boost/multiprecision/cpp_bin_float.hpp>
- #ifdef TEST_MPFR
- #include <boost/multiprecision/mpfr.hpp>
- #endif
- #include <boost/random/mersenne_twister.hpp>
- #include <boost/random/uniform_int.hpp>
- #include "libs/multiprecision/test/test.hpp"
- #include <iostream>
- #include <iomanip>
- template <class T>
- T generate_random()
- {
- typedef int e_type;
- static boost::random::mt19937 gen;
- T val = gen();
- T prev_val = -1;
- while (val != prev_val)
- {
- val *= (gen.max)();
- prev_val = val;
- val += gen();
- }
- e_type e;
- val = frexp(val, &e);
- static boost::random::uniform_int_distribution<e_type> ui(-20, 20);
- return ldexp(val, ui(gen));
- }
- using namespace boost::multiprecision;
- #ifdef TEST_MPFR
- typedef number<mpfr_float_backend<35> > good_type;
- #else
- typedef double good_type;
- #endif
- typedef number<cpp_bin_float<std::numeric_limits<good_type>::digits, digit_base_2>, et_off> test_type;
- void test_special_cases()
- {
- test_type max_val = (std::numeric_limits<test_type>::max)();
- test_type min_val = (std::numeric_limits<test_type>::min)();
- test_type eps = std::numeric_limits<test_type>::epsilon();
- test_type inf_val = (std::numeric_limits<test_type>::infinity)();
- test_type nan_val = (std::numeric_limits<test_type>::quiet_NaN)();
- test_type half = 0.5;
- test_type one_point_5 = 1.5;
- BOOST_CHECK((boost::math::isnormal)(max_val));
- BOOST_CHECK((boost::math::isnormal)(-max_val));
- BOOST_CHECK((boost::math::isnormal)(min_val));
- BOOST_CHECK((boost::math::isnormal)(-min_val));
- BOOST_CHECK((boost::math::isinf)(inf_val));
- BOOST_CHECK((boost::math::isinf)(-inf_val));
- BOOST_CHECK((boost::math::isnan)(nan_val));
- BOOST_CHECK((boost::math::isnan)(-nan_val));
- if (std::numeric_limits<test_type>::has_denorm)
- min_val = std::numeric_limits<test_type>::denorm_min();
- // Adding epsilon will increment 1.0:
- BOOST_CHECK(test_type(1) + eps != test_type(1));
- BOOST_CHECK(test_type(1) + eps / 2 == test_type(1));
- // But it's not the smallest value that will do that:
- test_type small = 1 + eps;
- small = ldexp(small, -std::numeric_limits<test_type>::digits);
- BOOST_CHECK(test_type(1) + small != test_type(1));
- // And if we increment 1.0 first, then an even smaller
- // addition will round up:
- test_type one_next = test_type(1) + eps;
- BOOST_CHECK(one_next + eps / 2 != one_next);
- // Overflow:
- BOOST_CHECK_EQUAL(max_val + max_val * eps, inf_val);
- BOOST_CHECK_EQUAL(-max_val - max_val * eps, -inf_val);
- BOOST_CHECK_EQUAL(max_val * 2, inf_val);
- BOOST_CHECK_EQUAL(max_val * -2, -inf_val);
- BOOST_CHECK_EQUAL(max_val / half, inf_val);
- BOOST_CHECK_EQUAL(max_val / -half, -inf_val);
- BOOST_CHECK_EQUAL(max_val / min_val, inf_val);
- BOOST_CHECK_EQUAL(max_val / -min_val, -inf_val);
- // Underflow:
- BOOST_CHECK_EQUAL(min_val * 2 - one_point_5 * min_val, 0);
- BOOST_CHECK_EQUAL(-min_val * 2 + one_point_5 * min_val, 0);
- BOOST_CHECK_EQUAL(min_val / 2, 0);
- BOOST_CHECK_EQUAL(min_val / max_val, 0);
- BOOST_CHECK_EQUAL(min_val * half, 0);
- BOOST_CHECK_EQUAL(min_val - min_val, 0);
- BOOST_CHECK_EQUAL(max_val - max_val, 0);
- BOOST_CHECK_EQUAL(-min_val + min_val, 0);
- BOOST_CHECK_EQUAL(-max_val + max_val, 0);
- // Things which should not over/underflow:
- BOOST_CHECK_EQUAL((min_val * 2) / 2, min_val);
- BOOST_CHECK_EQUAL((max_val / 2) * 2, max_val);
- BOOST_CHECK_GE((min_val * 2.0000001) / 1.9999999999999999, min_val);
- BOOST_CHECK_LE((max_val / 2.0000001) * 1.9999999999999999, max_val);
- BOOST_CHECK_EQUAL(min_val * 2 - min_val, min_val);
- BOOST_CHECK_EQUAL(max_val / 2 + max_val / 2, max_val);
- // Things involving zero:
- BOOST_CHECK_EQUAL(max_val + 0, max_val);
- BOOST_CHECK_EQUAL(max_val - 0, max_val);
- BOOST_CHECK_EQUAL(0 + max_val, max_val);
- BOOST_CHECK_EQUAL(0 - max_val, -max_val);
- BOOST_CHECK_EQUAL(max_val * 0, 0);
- BOOST_CHECK_EQUAL(0 * max_val, 0);
- BOOST_CHECK_EQUAL(max_val / 0, inf_val);
- BOOST_CHECK_EQUAL(0 / max_val, 0);
- BOOST_CHECK_EQUAL(-max_val / 0, -inf_val);
- BOOST_CHECK_EQUAL(0 / -max_val, 0);
- // Things involving infinity:
- BOOST_CHECK_EQUAL(inf_val + 2, inf_val);
- BOOST_CHECK_EQUAL(inf_val - 2, inf_val);
- BOOST_CHECK_EQUAL(inf_val + -2, inf_val);
- BOOST_CHECK_EQUAL(inf_val - -2, inf_val);
- BOOST_CHECK_EQUAL(-inf_val + 2, -inf_val);
- BOOST_CHECK_EQUAL(-inf_val - 2, -inf_val);
- BOOST_CHECK_EQUAL(-inf_val + -2, -inf_val);
- BOOST_CHECK_EQUAL(-inf_val - -2, -inf_val);
- BOOST_CHECK_EQUAL(2 + inf_val, inf_val);
- BOOST_CHECK_EQUAL(2 - inf_val, -inf_val);
- BOOST_CHECK_EQUAL(-2 + inf_val, inf_val);
- BOOST_CHECK_EQUAL(-2 - inf_val, -inf_val);
- BOOST_CHECK_EQUAL(2 + (-inf_val), -inf_val);
- BOOST_CHECK_EQUAL(2 - (-inf_val), inf_val);
- BOOST_CHECK_EQUAL(-2 + (-inf_val), -inf_val);
- BOOST_CHECK_EQUAL(-2 - (-inf_val), inf_val);
- BOOST_CHECK_EQUAL(sqrt(inf_val), inf_val);
- BOOST_CHECK(boost::math::isnan(sqrt(-inf_val)));
- BOOST_CHECK_EQUAL(inf_val + test_type(2), inf_val);
- BOOST_CHECK_EQUAL(inf_val - test_type(2), inf_val);
- BOOST_CHECK_EQUAL(inf_val + test_type(-2), inf_val);
- BOOST_CHECK_EQUAL(inf_val - test_type(-2), inf_val);
- BOOST_CHECK_EQUAL(-inf_val + test_type(2), -inf_val);
- BOOST_CHECK_EQUAL(-inf_val - test_type(2), -inf_val);
- BOOST_CHECK_EQUAL(-inf_val + test_type(-2), -inf_val);
- BOOST_CHECK_EQUAL(-inf_val - test_type(-2), -inf_val);
- BOOST_CHECK_EQUAL(test_type(2) + inf_val, inf_val);
- BOOST_CHECK_EQUAL(test_type(2) - inf_val, -inf_val);
- BOOST_CHECK_EQUAL(test_type(-2) + inf_val, inf_val);
- BOOST_CHECK_EQUAL(test_type(-2) - inf_val, -inf_val);
- BOOST_CHECK_EQUAL(test_type(2) + (-inf_val), -inf_val);
- BOOST_CHECK_EQUAL(test_type(2) - (-inf_val), inf_val);
- BOOST_CHECK_EQUAL(test_type(-2) + (-inf_val), -inf_val);
- BOOST_CHECK_EQUAL(test_type(-2) - (-inf_val), inf_val);
- BOOST_CHECK((boost::math::isnan)(inf_val - inf_val));
- BOOST_CHECK_EQUAL(inf_val * 2, inf_val);
- BOOST_CHECK_EQUAL(-inf_val * 2, -inf_val);
- BOOST_CHECK_EQUAL(inf_val * -2, -inf_val);
- BOOST_CHECK_EQUAL(-inf_val * -2, inf_val);
- BOOST_CHECK_EQUAL(inf_val * test_type(-2), -inf_val);
- BOOST_CHECK_EQUAL(-inf_val * test_type(-2), inf_val);
- BOOST_CHECK((boost::math::isnan)(inf_val * 0));
- BOOST_CHECK((boost::math::isnan)(-inf_val * 0));
- BOOST_CHECK_EQUAL(inf_val / 2, inf_val);
- BOOST_CHECK_EQUAL(-inf_val / 2, -inf_val);
- BOOST_CHECK_EQUAL(inf_val / -2, -inf_val);
- BOOST_CHECK_EQUAL(-inf_val / -2, inf_val);
- BOOST_CHECK_EQUAL(inf_val / test_type(-2), -inf_val);
- BOOST_CHECK_EQUAL(-inf_val / test_type(-2), inf_val);
- BOOST_CHECK_EQUAL(inf_val / 0, inf_val);
- BOOST_CHECK_EQUAL(-inf_val / 0, -inf_val);
- BOOST_CHECK((boost::math::isnan)(inf_val / inf_val));
- BOOST_CHECK((boost::math::isnan)(-inf_val / inf_val));
- // Things involving nan:
- BOOST_CHECK((boost::math::isnan)(nan_val + 2));
- BOOST_CHECK((boost::math::isnan)(nan_val - 2));
- BOOST_CHECK((boost::math::isnan)(nan_val + 0));
- BOOST_CHECK((boost::math::isnan)(nan_val - 0));
- BOOST_CHECK((boost::math::isnan)(nan_val + inf_val));
- BOOST_CHECK((boost::math::isnan)(nan_val - inf_val));
- BOOST_CHECK((boost::math::isnan)(nan_val + nan_val));
- BOOST_CHECK((boost::math::isnan)(nan_val - nan_val));
- BOOST_CHECK((boost::math::isnan)(2 + nan_val));
- BOOST_CHECK((boost::math::isnan)(2 - nan_val));
- BOOST_CHECK((boost::math::isnan)(0 - nan_val));
- BOOST_CHECK((boost::math::isnan)(0 - nan_val));
- BOOST_CHECK((boost::math::isnan)(inf_val + nan_val));
- BOOST_CHECK((boost::math::isnan)(inf_val - nan_val));
- BOOST_CHECK((boost::math::isnan)(nan_val * 2));
- BOOST_CHECK((boost::math::isnan)(nan_val / 2));
- BOOST_CHECK((boost::math::isnan)(nan_val * 0));
- BOOST_CHECK((boost::math::isnan)(nan_val / 0));
- BOOST_CHECK((boost::math::isnan)(nan_val * inf_val));
- BOOST_CHECK((boost::math::isnan)(nan_val / inf_val));
- BOOST_CHECK((boost::math::isnan)(nan_val * nan_val));
- BOOST_CHECK((boost::math::isnan)(nan_val / nan_val));
- BOOST_CHECK((boost::math::isnan)(2 * nan_val));
- BOOST_CHECK((boost::math::isnan)(2 / nan_val));
- BOOST_CHECK((boost::math::isnan)(0 / nan_val));
- BOOST_CHECK((boost::math::isnan)(0 / nan_val));
- BOOST_CHECK((boost::math::isnan)(inf_val * nan_val));
- BOOST_CHECK((boost::math::isnan)(inf_val / nan_val));
- // Corner cases:
- BOOST_CHECK_EQUAL((max_val * half) / half, max_val);
- BOOST_CHECK_EQUAL((max_val / 2) * 2, max_val);
- BOOST_CHECK_EQUAL((min_val / half) * half, min_val);
- BOOST_CHECK_EQUAL((min_val * 2) / 2, min_val);
- BOOST_CHECK_EQUAL(max_val + min_val, max_val);
- BOOST_CHECK_EQUAL(min_val + max_val, max_val);
- BOOST_CHECK_EQUAL(max_val - min_val, max_val);
- BOOST_CHECK_EQUAL(min_val - max_val, -max_val);
- // Signed zeros:
- BOOST_CHECK(boost::math::signbit(min_val * -min_val));
- BOOST_CHECK(boost::math::signbit(min_val * min_val) == 0);
- BOOST_CHECK(boost::math::signbit(-min_val * -min_val) == 0);
- BOOST_CHECK(boost::math::signbit(-min_val * min_val));
- BOOST_CHECK(boost::math::signbit(min_val / max_val) == 0);
- BOOST_CHECK(boost::math::signbit(min_val / -max_val));
- BOOST_CHECK(boost::math::signbit(-min_val / -max_val) == 0);
- BOOST_CHECK(boost::math::signbit(-min_val / max_val));
- BOOST_CHECK(boost::math::signbit(min_val / 2) == 0);
- BOOST_CHECK(boost::math::signbit(min_val / -2));
- BOOST_CHECK(boost::math::signbit(-min_val / -2) == 0);
- BOOST_CHECK(boost::math::signbit(-min_val / 2));
- test_type neg_zero = min_val * -min_val;
- test_type zero = 0;
- // Arithmetic involving signed zero:
- BOOST_CHECK_EQUAL(-neg_zero, 0);
- BOOST_CHECK(!boost::math::signbit(-neg_zero));
- BOOST_CHECK_EQUAL(neg_zero + 2, 2);
- BOOST_CHECK_EQUAL(neg_zero + test_type(2), 2);
- BOOST_CHECK_EQUAL(2 + neg_zero, 2);
- BOOST_CHECK_EQUAL(test_type(2) + neg_zero, 2);
- BOOST_CHECK_EQUAL(neg_zero + -2, -2);
- BOOST_CHECK_EQUAL(neg_zero + test_type(-2), -2);
- BOOST_CHECK_EQUAL(-2 + neg_zero, -2);
- BOOST_CHECK_EQUAL(test_type(-2) + neg_zero, -2);
- BOOST_CHECK_EQUAL(neg_zero - 2, -2);
- BOOST_CHECK_EQUAL(neg_zero - test_type(2), -2);
- BOOST_CHECK_EQUAL(2 - neg_zero, 2);
- BOOST_CHECK_EQUAL(test_type(2) - neg_zero, 2);
- BOOST_CHECK_EQUAL(neg_zero - -2, 2);
- BOOST_CHECK_EQUAL(neg_zero - test_type(-2), 2);
- BOOST_CHECK_EQUAL(-2 - neg_zero, -2);
- BOOST_CHECK_EQUAL(test_type(-2) - neg_zero, -2);
- BOOST_CHECK(!boost::math::signbit(test_type(2) + test_type(-2)));
- BOOST_CHECK(!boost::math::signbit(test_type(2) - test_type(2)));
- BOOST_CHECK(!boost::math::signbit(test_type(-2) - test_type(-2)));
- BOOST_CHECK(!boost::math::signbit(test_type(-2) + test_type(2)));
- BOOST_CHECK(!boost::math::signbit(zero + zero));
- BOOST_CHECK(!boost::math::signbit(zero - zero));
- BOOST_CHECK(!boost::math::signbit(neg_zero + zero));
- BOOST_CHECK(!boost::math::signbit(zero + neg_zero));
- BOOST_CHECK(boost::math::signbit(neg_zero + neg_zero));
- BOOST_CHECK(boost::math::signbit(neg_zero - zero));
- BOOST_CHECK(!boost::math::signbit(zero - neg_zero));
- BOOST_CHECK(!boost::math::signbit(neg_zero - neg_zero));
- small = 0.25;
- BOOST_CHECK(!boost::math::signbit(floor(small)));
- BOOST_CHECK(!boost::math::signbit(round(small)));
- BOOST_CHECK(!boost::math::signbit(trunc(small)));
- small = -small;
- BOOST_CHECK(boost::math::signbit(ceil(small)));
- BOOST_CHECK(boost::math::signbit(round(small)));
- BOOST_CHECK(boost::math::signbit(trunc(small)));
- BOOST_CHECK_EQUAL(neg_zero * 2, 0);
- BOOST_CHECK_EQUAL(neg_zero * test_type(2), 0);
- BOOST_CHECK_EQUAL(2 * neg_zero, 0);
- BOOST_CHECK_EQUAL(test_type(2) * neg_zero, 0);
- BOOST_CHECK_EQUAL(neg_zero * -2, 0);
- BOOST_CHECK_EQUAL(neg_zero * test_type(-2), 0);
- BOOST_CHECK_EQUAL(-2 * neg_zero, 0);
- BOOST_CHECK_EQUAL(test_type(-2) * neg_zero, 0);
- BOOST_CHECK(boost::math::signbit(neg_zero * 2));
- BOOST_CHECK(boost::math::signbit(neg_zero * test_type(2)));
- BOOST_CHECK(boost::math::signbit(2 * neg_zero));
- BOOST_CHECK(boost::math::signbit(test_type(2) * neg_zero));
- BOOST_CHECK(!boost::math::signbit(neg_zero * -2));
- BOOST_CHECK(!boost::math::signbit(neg_zero * test_type(-2)));
- BOOST_CHECK(!boost::math::signbit(-2 * neg_zero));
- BOOST_CHECK(!boost::math::signbit(test_type(-2) * neg_zero));
- BOOST_CHECK_EQUAL(neg_zero / 2, 0);
- BOOST_CHECK_EQUAL(neg_zero / test_type(2), 0);
- BOOST_CHECK_EQUAL(2 / neg_zero, -inf_val);
- BOOST_CHECK_EQUAL(test_type(2) / neg_zero, -inf_val);
- BOOST_CHECK_EQUAL(neg_zero / -2, 0);
- BOOST_CHECK_EQUAL(neg_zero / test_type(-2), 0);
- BOOST_CHECK_EQUAL(-2 / neg_zero, inf_val);
- BOOST_CHECK_EQUAL(test_type(-2) / neg_zero, inf_val);
- BOOST_CHECK(boost::math::signbit(neg_zero / 2));
- BOOST_CHECK(boost::math::signbit(neg_zero / test_type(2)));
- BOOST_CHECK(boost::math::signbit(2 / neg_zero));
- BOOST_CHECK(boost::math::signbit(test_type(2) / neg_zero));
- BOOST_CHECK(!boost::math::signbit(neg_zero / -2));
- BOOST_CHECK(!boost::math::signbit(neg_zero / test_type(-2)));
- BOOST_CHECK(!boost::math::signbit(-2 / neg_zero));
- BOOST_CHECK(!boost::math::signbit(test_type(-2) / neg_zero));
- BOOST_CHECK(boost::math::signbit(neg_zero.convert_to<double>()));
- BOOST_CHECK(boost::math::signbit(neg_zero.convert_to<float>()));
- BOOST_CHECK(boost::math::signbit(neg_zero.convert_to<long double>()));
- BOOST_CHECK(!boost::math::signbit(zero.convert_to<double>()));
- BOOST_CHECK(!boost::math::signbit(zero.convert_to<float>()));
- BOOST_CHECK(!boost::math::signbit(zero.convert_to<long double>()));
- // Conversions to other types of special values:
- if (std::numeric_limits<float>::has_infinity)
- {
- BOOST_CHECK_EQUAL(inf_val.convert_to<float>(), std::numeric_limits<float>::infinity());
- BOOST_CHECK_EQUAL((-inf_val).convert_to<float>(), -std::numeric_limits<float>::infinity());
- }
- if (std::numeric_limits<float>::has_quiet_NaN)
- {
- BOOST_CHECK((boost::math::isnan)(nan_val.convert_to<float>()));
- }
- if (std::numeric_limits<double>::has_infinity)
- {
- BOOST_CHECK_EQUAL(inf_val.convert_to<double>(), std::numeric_limits<double>::infinity());
- BOOST_CHECK_EQUAL((-inf_val).convert_to<double>(), -std::numeric_limits<double>::infinity());
- }
- if (std::numeric_limits<double>::has_quiet_NaN)
- {
- BOOST_CHECK((boost::math::isnan)(nan_val.convert_to<double>()));
- }
- if (std::numeric_limits<long double>::has_infinity)
- {
- BOOST_CHECK_EQUAL(inf_val.convert_to<long double>(), std::numeric_limits<long double>::infinity());
- BOOST_CHECK_EQUAL((-inf_val).convert_to<long double>(), -std::numeric_limits<long double>::infinity());
- }
- if (std::numeric_limits<long double>::has_quiet_NaN)
- {
- BOOST_CHECK((boost::math::isnan)(nan_val.convert_to<long double>()));
- }
- //
- // Bug https://svn.boost.org/trac/boost/attachment/ticket/12580
- //
- using std::ldexp;
- test_type a(1);
- test_type b = ldexp(test_type(0.99), -std::numeric_limits<test_type>::digits);
- good_type ga(1);
- good_type gb = ldexp(good_type(0.99), -std::numeric_limits<good_type>::digits);
- BOOST_CHECK_EQUAL(good_type(test_type(a - b)), good_type(ga - gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b - a)), good_type(gb - ga));
- BOOST_CHECK_EQUAL(good_type(test_type(a + b)), good_type(ga + gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b + a)), good_type(gb + ga));
- BOOST_CHECK_EQUAL(good_type(test_type(a - -b)), good_type(ga - -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b - -a)), good_type(gb - -ga));
- BOOST_CHECK_EQUAL(good_type(test_type(a + -b)), good_type(ga + -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b + -a)), good_type(gb + -ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a - b)), good_type(-ga - gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b - a)), good_type(-gb - ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a + b)), good_type(-ga + gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b + a)), good_type(-gb + ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a - -b)), good_type(-ga - -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b - -a)), good_type(-gb - -ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a + -b)), good_type(-ga + -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b + -a)), good_type(-gb + -ga));
- b = ldexp(test_type(0.5), -std::numeric_limits<test_type>::digits);
- gb = ldexp(good_type(0.5), -std::numeric_limits<good_type>::digits);
- BOOST_CHECK_EQUAL(good_type(test_type(a - b)), good_type(ga - gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b - a)), good_type(gb - ga));
- BOOST_CHECK_EQUAL(good_type(test_type(a + b)), good_type(ga + gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b + a)), good_type(gb + ga));
- BOOST_CHECK_EQUAL(good_type(test_type(a - -b)), good_type(ga - -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b - -a)), good_type(gb - -ga));
- BOOST_CHECK_EQUAL(good_type(test_type(a + -b)), good_type(ga + -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b + -a)), good_type(gb + -ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a - b)), good_type(-ga - gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b - a)), good_type(-gb - ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a + b)), good_type(-ga + gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b + a)), good_type(-gb + ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a - -b)), good_type(-ga - -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b - -a)), good_type(-gb - -ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a + -b)), good_type(-ga + -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b + -a)), good_type(-gb + -ga));
- b = ldexp(test_type(1), -std::numeric_limits<test_type>::digits);
- gb = ldexp(good_type(1), -std::numeric_limits<good_type>::digits);
- BOOST_CHECK_EQUAL(good_type(test_type(a - b)), good_type(ga - gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b - a)), good_type(gb - ga));
- BOOST_CHECK_EQUAL(good_type(test_type(a + b)), good_type(ga + gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b + a)), good_type(gb + ga));
- BOOST_CHECK_EQUAL(good_type(test_type(a - -b)), good_type(ga - -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b - -a)), good_type(gb - -ga));
- BOOST_CHECK_EQUAL(good_type(test_type(a + -b)), good_type(ga + -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b + -a)), good_type(gb + -ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a - b)), good_type(-ga - gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b - a)), good_type(-gb - ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a + b)), good_type(-ga + gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b + a)), good_type(-gb + ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a - -b)), good_type(-ga - -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b - -a)), good_type(-gb - -ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a + -b)), good_type(-ga + -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b + -a)), good_type(-gb + -ga));
- b = ldexp(test_type(0.50000000001), -std::numeric_limits<test_type>::digits);
- gb = ldexp(good_type(0.50000000001), -std::numeric_limits<good_type>::digits);
- BOOST_CHECK_EQUAL(good_type(test_type(a - b)), good_type(ga - gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b - a)), good_type(gb - ga));
- BOOST_CHECK_EQUAL(good_type(test_type(a + b)), good_type(ga + gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b + a)), good_type(gb + ga));
- BOOST_CHECK_EQUAL(good_type(test_type(a - -b)), good_type(ga - -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b - -a)), good_type(gb - -ga));
- BOOST_CHECK_EQUAL(good_type(test_type(a + -b)), good_type(ga + -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b + -a)), good_type(gb + -ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a - b)), good_type(-ga - gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b - a)), good_type(-gb - ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a + b)), good_type(-ga + gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b + a)), good_type(-gb + ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a - -b)), good_type(-ga - -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b - -a)), good_type(-gb - -ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a + -b)), good_type(-ga + -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b + -a)), good_type(-gb + -ga));
- a = a + ldexp(a, -20);
- ga = ga + ldexp(ga, -20);
- BOOST_CHECK_EQUAL(good_type(test_type(a - b)), good_type(ga - gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b - a)), good_type(gb - ga));
- BOOST_CHECK_EQUAL(good_type(test_type(a + b)), good_type(ga + gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b + a)), good_type(gb + ga));
- BOOST_CHECK_EQUAL(good_type(test_type(a - -b)), good_type(ga - -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b - -a)), good_type(gb - -ga));
- BOOST_CHECK_EQUAL(good_type(test_type(a + -b)), good_type(ga + -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b + -a)), good_type(gb + -ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a - b)), good_type(-ga - gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b - a)), good_type(-gb - ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a + b)), good_type(-ga + gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b + a)), good_type(-gb + ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a - -b)), good_type(-ga - -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b - -a)), good_type(-gb - -ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a + -b)), good_type(-ga + -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b + -a)), good_type(-gb + -ga));
- b = ldexp(test_type(0.5), -std::numeric_limits<test_type>::digits);
- gb = ldexp(good_type(0.5), -std::numeric_limits<good_type>::digits);
- BOOST_CHECK_EQUAL(good_type(test_type(a - b)), good_type(ga - gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b - a)), good_type(gb - ga));
- BOOST_CHECK_EQUAL(good_type(test_type(a + b)), good_type(ga + gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b + a)), good_type(gb + ga));
- BOOST_CHECK_EQUAL(good_type(test_type(a - -b)), good_type(ga - -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b - -a)), good_type(gb - -ga));
- BOOST_CHECK_EQUAL(good_type(test_type(a + -b)), good_type(ga + -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b + -a)), good_type(gb + -ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a - b)), good_type(-ga - gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b - a)), good_type(-gb - ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a + b)), good_type(-ga + gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b + a)), good_type(-gb + ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a - -b)), good_type(-ga - -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b - -a)), good_type(-gb - -ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a + -b)), good_type(-ga + -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b + -a)), good_type(-gb + -ga));
- b = ldexp(test_type(1), -std::numeric_limits<test_type>::digits);
- gb = ldexp(good_type(1), -std::numeric_limits<good_type>::digits);
- BOOST_CHECK_EQUAL(good_type(test_type(a - b)), good_type(ga - gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b - a)), good_type(gb - ga));
- BOOST_CHECK_EQUAL(good_type(test_type(a + b)), good_type(ga + gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b + a)), good_type(gb + ga));
- BOOST_CHECK_EQUAL(good_type(test_type(a - -b)), good_type(ga - -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b - -a)), good_type(gb - -ga));
- BOOST_CHECK_EQUAL(good_type(test_type(a + -b)), good_type(ga + -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b + -a)), good_type(gb + -ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a - b)), good_type(-ga - gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b - a)), good_type(-gb - ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a + b)), good_type(-ga + gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b + a)), good_type(-gb + ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a - -b)), good_type(-ga - -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b - -a)), good_type(-gb - -ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a + -b)), good_type(-ga + -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b + -a)), good_type(-gb + -ga));
- b = ldexp(test_type(0.50000000001), -std::numeric_limits<test_type>::digits);
- gb = ldexp(good_type(0.50000000001), -std::numeric_limits<good_type>::digits);
- BOOST_CHECK_EQUAL(good_type(test_type(a - b)), good_type(ga - gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b - a)), good_type(gb - ga));
- BOOST_CHECK_EQUAL(good_type(test_type(a + b)), good_type(ga + gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b + a)), good_type(gb + ga));
- BOOST_CHECK_EQUAL(good_type(test_type(a - -b)), good_type(ga - -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b - -a)), good_type(gb - -ga));
- BOOST_CHECK_EQUAL(good_type(test_type(a + -b)), good_type(ga + -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b + -a)), good_type(gb + -ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a - b)), good_type(-ga - gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b - a)), good_type(-gb - ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a + b)), good_type(-ga + gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b + a)), good_type(-gb + ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a - -b)), good_type(-ga - -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b - -a)), good_type(-gb - -ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a + -b)), good_type(-ga + -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b + -a)), good_type(-gb + -ga));
- a = 1;
- a = boost::math::float_prior(a);
- ga = 1;
- ga = boost::math::float_prior(ga);
- BOOST_CHECK_EQUAL(good_type(test_type(a - b)), good_type(ga - gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b - a)), good_type(gb - ga));
- BOOST_CHECK_EQUAL(good_type(test_type(a + b)), good_type(ga + gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b + a)), good_type(gb + ga));
- BOOST_CHECK_EQUAL(good_type(test_type(a - -b)), good_type(ga - -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b - -a)), good_type(gb - -ga));
- BOOST_CHECK_EQUAL(good_type(test_type(a + -b)), good_type(ga + -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b + -a)), good_type(gb + -ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a - b)), good_type(-ga - gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b - a)), good_type(-gb - ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a + b)), good_type(-ga + gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b + a)), good_type(-gb + ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a - -b)), good_type(-ga - -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b - -a)), good_type(-gb - -ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a + -b)), good_type(-ga + -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b + -a)), good_type(-gb + -ga));
- b = ldexp(test_type(0.5), -std::numeric_limits<test_type>::digits);
- gb = ldexp(good_type(0.5), -std::numeric_limits<good_type>::digits);
- BOOST_CHECK_EQUAL(good_type(test_type(a - b)), good_type(ga - gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b - a)), good_type(gb - ga));
- BOOST_CHECK_EQUAL(good_type(test_type(a + b)), good_type(ga + gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b + a)), good_type(gb + ga));
- BOOST_CHECK_EQUAL(good_type(test_type(a - -b)), good_type(ga - -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b - -a)), good_type(gb - -ga));
- BOOST_CHECK_EQUAL(good_type(test_type(a + -b)), good_type(ga + -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b + -a)), good_type(gb + -ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a - b)), good_type(-ga - gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b - a)), good_type(-gb - ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a + b)), good_type(-ga + gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b + a)), good_type(-gb + ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a - -b)), good_type(-ga - -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b - -a)), good_type(-gb - -ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a + -b)), good_type(-ga + -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b + -a)), good_type(-gb + -ga));
- b = ldexp(test_type(1), -std::numeric_limits<test_type>::digits);
- gb = ldexp(good_type(1), -std::numeric_limits<good_type>::digits);
- BOOST_CHECK_EQUAL(good_type(test_type(a - b)), good_type(ga - gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b - a)), good_type(gb - ga));
- BOOST_CHECK_EQUAL(good_type(test_type(a + b)), good_type(ga + gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b + a)), good_type(gb + ga));
- BOOST_CHECK_EQUAL(good_type(test_type(a - -b)), good_type(ga - -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b - -a)), good_type(gb - -ga));
- BOOST_CHECK_EQUAL(good_type(test_type(a + -b)), good_type(ga + -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b + -a)), good_type(gb + -ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a - b)), good_type(-ga - gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b - a)), good_type(-gb - ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a + b)), good_type(-ga + gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b + a)), good_type(-gb + ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a - -b)), good_type(-ga - -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b - -a)), good_type(-gb - -ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a + -b)), good_type(-ga + -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b + -a)), good_type(-gb + -ga));
- b = ldexp(test_type(0.50000000001), -std::numeric_limits<test_type>::digits);
- gb = ldexp(good_type(0.50000000001), -std::numeric_limits<good_type>::digits);
- BOOST_CHECK_EQUAL(good_type(test_type(a - b)), good_type(ga - gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b - a)), good_type(gb - ga));
- BOOST_CHECK_EQUAL(good_type(test_type(a + b)), good_type(ga + gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b + a)), good_type(gb + ga));
- BOOST_CHECK_EQUAL(good_type(test_type(a - -b)), good_type(ga - -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b - -a)), good_type(gb - -ga));
- BOOST_CHECK_EQUAL(good_type(test_type(a + -b)), good_type(ga + -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(b + -a)), good_type(gb + -ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a - b)), good_type(-ga - gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b - a)), good_type(-gb - ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a + b)), good_type(-ga + gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b + a)), good_type(-gb + ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a - -b)), good_type(-ga - -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b - -a)), good_type(-gb - -ga));
- BOOST_CHECK_EQUAL(good_type(test_type(-a + -b)), good_type(-ga + -gb));
- BOOST_CHECK_EQUAL(good_type(test_type(-b + -a)), good_type(-gb + -ga));
- }
- int main()
- {
- test_special_cases();
- unsigned error_count = 0;
- for (unsigned i = 0; i < 100000; ++i)
- {
- good_type a = generate_random<good_type>();
- good_type b = generate_random<good_type>();
- test_type ta(a);
- test_type tb(b);
- BOOST_CHECK_EQUAL(test_type(a * b), ta * tb);
- BOOST_CHECK_EQUAL(test_type(-a * b), -ta * tb);
- BOOST_CHECK_EQUAL(test_type(a * -b), ta * -tb);
- BOOST_CHECK_EQUAL(test_type(-a * -b), -ta * -tb);
- BOOST_CHECK_EQUAL(test_type(a + b), ta + tb);
- BOOST_CHECK_EQUAL(test_type(-a + b), -ta + tb);
- BOOST_CHECK_EQUAL(test_type(a + -b), ta + -tb);
- BOOST_CHECK_EQUAL(test_type(-a + -b), -ta + -tb);
- BOOST_CHECK_EQUAL(test_type(a - b), ta - tb);
- BOOST_CHECK_EQUAL(test_type(-a - b), -ta - tb);
- BOOST_CHECK_EQUAL(test_type(a - -b), ta - -tb);
- BOOST_CHECK_EQUAL(test_type(-a - -b), -ta - -tb);
- BOOST_CHECK_EQUAL(test_type(a / b), ta / tb);
- BOOST_CHECK_EQUAL(test_type(-a / b), -ta / tb);
- BOOST_CHECK_EQUAL(test_type(a / -b), ta / -tb);
- BOOST_CHECK_EQUAL(test_type(-a / -b), -ta / -tb);
- BOOST_CHECK_EQUAL(test_type(sqrt(a)), sqrt(ta));
- BOOST_CHECK_EQUAL(test_type(floor(a)), floor(ta));
- BOOST_CHECK_EQUAL(test_type(floor(-a)), floor(-ta));
- BOOST_CHECK_EQUAL(test_type(ceil(a)), ceil(ta));
- BOOST_CHECK_EQUAL(test_type(ceil(-a)), ceil(-ta));
- #ifdef TEST_MPFR
- //
- // Conversions:
- //
- BOOST_CHECK_EQUAL(a.convert_to<double>(), ta.convert_to<double>());
- BOOST_CHECK_EQUAL(a.convert_to<float>(), ta.convert_to<float>());
- BOOST_CHECK_EQUAL(b.convert_to<double>(), tb.convert_to<double>());
- BOOST_CHECK_EQUAL(b.convert_to<float>(), tb.convert_to<float>());
- #else
- BOOST_CHECK_EQUAL(a, ta.convert_to<double>());
- BOOST_CHECK_EQUAL(static_cast<float>(a), ta.convert_to<float>());
- BOOST_CHECK_EQUAL(b, tb.convert_to<double>());
- BOOST_CHECK_EQUAL(static_cast<float>(b), tb.convert_to<float>());
- #endif
- static boost::random::mt19937 i_gen;
- int si = i_gen();
- BOOST_CHECK_EQUAL(test_type(a * si), ta * si);
- BOOST_CHECK_EQUAL(test_type(-a * si), -ta * si);
- BOOST_CHECK_EQUAL(test_type(-a * -si), -ta * -si);
- BOOST_CHECK_EQUAL(test_type(a * -si), ta * -si);
- unsigned ui = std::abs(si);
- BOOST_CHECK_EQUAL(test_type(a * ui), ta * ui);
- BOOST_CHECK_EQUAL(test_type(-a * ui), -ta * ui);
- // Divide:
- BOOST_CHECK_EQUAL(test_type(a / si), ta / si);
- BOOST_CHECK_EQUAL(test_type(-a / si), -ta / si);
- BOOST_CHECK_EQUAL(test_type(-a / -si), -ta / -si);
- BOOST_CHECK_EQUAL(test_type(a / -si), ta / -si);
- BOOST_CHECK_EQUAL(test_type(a / ui), ta / ui);
- BOOST_CHECK_EQUAL(test_type(-a / ui), -ta / ui);
- // Error reporting:
- if (boost::detail::test_errors() != error_count)
- {
- error_count = boost::detail::test_errors();
- std::cout << std::setprecision(std::numeric_limits<test_type>::max_digits10) << std::scientific;
- std::cout << "a (mpfr) = " << a << std::endl;
- std::cout << "a (test) = " << ta << std::endl;
- std::cout << "b (mpfr) = " << b << std::endl;
- std::cout << "b (test) = " << tb << std::endl;
- std::cout << "si = " << si << std::endl;
- std::cout << "ui = " << ui << std::endl;
- }
- }
- return boost::report_errors();
- }
|