#include #include #include #include #include #include #include #if 0 // TBD: Quadmath support when available #include #endif // cd /mnt/c/Users/User/Documents/Ks/PC_Software/Test // g++ -Wall -Wextra -O3 -std=gnu++11 -I/mnt/c/MyGitRepos/BoostGSoC21_multiprecision/include -I/mnt/c/boost/boost_1_76_0 test.cpp -o test.exe namespace test_arithmetic_cpp_double_float { std::mt19937 engine_man; std::ranlux24_base engine_sgn; std::linear_congruential_engine engine_dec_pt; template void get_random_fixed_string(std::string& str) { static std::uniform_int_distribution dist_sgn( 0, 1); static std::uniform_int_distribution dist_dec_pt( 1, (int)(std::max)(std::ptrdiff_t(2), std::ptrdiff_t(std::ptrdiff_t(DigitsToGet) - 4))); static std::uniform_int_distribution dist_first( 1, 9); static std::uniform_int_distribution dist_following( 0, 9); const bool is_neg = (dist_sgn(engine_sgn) != 0); std::string::size_type len = static_cast(DigitsToGet); std::string::size_type pos = 0U; if (is_neg) { ++len; str.resize(len); str.at(pos) = char('-'); ++pos; } else { str.resize(len); } str.at(pos) = static_cast(dist_first(engine_man) + 0x30U); ++pos; const std::string::size_type pos_dec_pt = pos + std::string::size_type(dist_dec_pt(engine_dec_pt)); while (pos < str.length()) { if (pos == pos_dec_pt) { ++len; str.resize(len); str.at(pos) = char('.'); ++pos; } str.at(pos) = static_cast(dist_following(engine_man) + 0x30U); ++pos; } } const unsigned int ErrorThreshold = 1000U; template int test_add(const unsigned count = 10000U) { using naked_double_float_type = boost::multiprecision::backends::cpp_double_float; using control_float_type = boost::multiprecision::number::digits10 + 2>, boost::multiprecision::et_off>; std::cout << "testing operator+..."; bool result_is_ok = true; for(unsigned i = 0U; i < count; ++i) { std::string str_a; std::string str_b; test_arithmetic_cpp_double_float::get_random_fixed_string::digits10>(str_a); test_arithmetic_cpp_double_float::get_random_fixed_string::digits10>(str_b); const naked_double_float_type df_a (str_a); const naked_double_float_type df_b (str_b); const control_float_type ctrl_a(str_a); const control_float_type ctrl_b(str_b); naked_double_float_type df_c = df_a + df_b; control_float_type ctrl_c = ctrl_a + ctrl_b; std::stringstream strm; strm << std::setprecision(std::numeric_limits::digits10) << df_c; const std::string str_df_c = strm.str(); const bool b_ok = (fabs(1 - fabs(ctrl_c / control_float_type(str_df_c))) < std::numeric_limits::epsilon() * ErrorThreshold); if (!b_ok) { std::cerr << " [FAILED] while performing '" << str_a << "' + '" << str_b << "'" << std::endl; return -1; } } std::cout << " ok" << std::endl; return 0; } template int test_sub(const unsigned count = 10000U) { using naked_double_float_type = boost::multiprecision::backends::cpp_double_float; using control_float_type = boost::multiprecision::number::digits10 + 2>, boost::multiprecision::et_off>; std::cout << "testing operator-..."; bool result_is_ok = true; for (unsigned i = 0U; i < count; ++i) { std::string str_a; std::string str_b; test_arithmetic_cpp_double_float::get_random_fixed_string::digits10>(str_a); test_arithmetic_cpp_double_float::get_random_fixed_string::digits10>(str_b); const naked_double_float_type df_a(str_a); const naked_double_float_type df_b(str_b); const control_float_type ctrl_a(str_a); const control_float_type ctrl_b(str_b); naked_double_float_type df_c = df_a - df_b; control_float_type ctrl_c = ctrl_a - ctrl_b; std::stringstream strm; strm << std::setprecision(std::numeric_limits::digits10) << df_c; const std::string str_df_c = strm.str(); const bool b_ok = (fabs(1 - fabs(ctrl_c / control_float_type(str_df_c))) < std::numeric_limits::epsilon() * ErrorThreshold); if (!b_ok) { std::cerr << " [FAILED] while performing '" << str_a << "' - '" << str_b << "'" << std::endl; return -1; } } std::cout << " ok" << std::endl; return 0; } template int test_mul(const unsigned count = 10000U) { using naked_double_float_type = boost::multiprecision::backends::cpp_double_float; using control_float_type = boost::multiprecision::number::digits10 + 2>, boost::multiprecision::et_off>; std::cout << "testing operator*..."; bool result_is_ok = true; for (unsigned i = 0U; i < count; ++i) { std::string str_a; std::string str_b; test_arithmetic_cpp_double_float::get_random_fixed_string::digits10>(str_a); test_arithmetic_cpp_double_float::get_random_fixed_string::digits10>(str_b); const naked_double_float_type df_a(str_a); const naked_double_float_type df_b(str_b); const control_float_type ctrl_a(str_a); const control_float_type ctrl_b(str_b); naked_double_float_type df_c = df_a * df_b; control_float_type ctrl_c = ctrl_a * ctrl_b; std::stringstream strm; strm << std::setprecision(std::numeric_limits::digits10) << df_c; const std::string str_df_c = strm.str(); const bool b_ok = (fabs(1 - fabs(ctrl_c / control_float_type(str_df_c))) < std::numeric_limits::epsilon() * ErrorThreshold); if (!b_ok) { std::cerr << " [FAILED] while performing '" << str_a << "' * '" << str_b << "'" << std::endl; return -1; } } std::cout << " ok" << std::endl; return 0; } template int test_div(const unsigned count = 10000U) { using naked_double_float_type = boost::multiprecision::backends::cpp_double_float; using control_float_type = boost::multiprecision::number::digits10 + 2>, boost::multiprecision::et_off>; std::cout << "testing operator/..."; bool result_is_ok = true; for (unsigned i = 0U; i < count; ++i) { std::string str_a; std::string str_b; test_arithmetic_cpp_double_float::get_random_fixed_string::digits10>(str_a); test_arithmetic_cpp_double_float::get_random_fixed_string::digits10>(str_b); const naked_double_float_type df_a(str_a); const naked_double_float_type df_b(str_b); const control_float_type ctrl_a(str_a); const control_float_type ctrl_b(str_b); naked_double_float_type df_c = df_a / df_b; control_float_type ctrl_c = ctrl_a / ctrl_b; std::stringstream strm; strm << std::setprecision(std::numeric_limits::digits10) << df_c; const std::string str_df_c = strm.str(); const bool b_ok = (fabs(1 - fabs(ctrl_c / control_float_type(str_df_c))) < std::numeric_limits::epsilon() * ErrorThreshold); if (!b_ok) { std::cerr << " [FAILED] while performing '" << str_a << "' / '" << str_b << "'" << std::endl; return -1; } } std::cout << " ok" << std::endl; return 0; } template bool test_basic() { std::cout << "Testing basic arithmetic for cpp_double_float<" << typeid(T).name() << ">" << std::endl; int e = 0; e += test_add(); e += test_sub(); e += test_mul(); e += test_div(); std::cout << std::endl; return e; } } // namespace test_arithmetic_cpp_double_float int main() { test_arithmetic_cpp_double_float::test_basic(); test_arithmetic_cpp_double_float::test_basic(); }