mirror of
https://github.com/boostorg/multiprecision.git
synced 2026-01-27 07:02:10 +00:00
Very preliminary backend but no 128 yet
This commit is contained in:
@@ -12,7 +12,7 @@
|
||||
// g++ -O3 -Wall -march=native -std=c++11 -I/mnt/c/MyGitRepos/BoostGSoC21_multiprecision/include -I/mnt/c/boost/boost_1_76_0 test.cpp -o test_double_float.exe
|
||||
|
||||
// TBD: Handle interaction with Boost's wrap of libquadmath __float128.
|
||||
// g++ -O3 -Wall -march=native -std=gnu++11 -I/mnt/c/MyGitRepos/BoostGSoC21_multiprecision/include -I/mnt/c/boost/boost_1_76_0 -DBOOST_MATH_USE_FLOAT128 test.cpp -o -lquadmath test_double_float.exe
|
||||
// g++ -O3 -Wall -march=native -std=gnu++11 -I/mnt/c/MyGitRepos/BoostGSoC21_multiprecision/include -I/mnt/c/boost/boost_1_76_0 -DBOOST_MATH_USE_FLOAT128 test.cpp -lquadmath -o test_double_float.exe
|
||||
|
||||
#include <ctime>
|
||||
#include <iomanip>
|
||||
@@ -59,19 +59,21 @@ int rand_in_range(int a, int b)
|
||||
}
|
||||
|
||||
template <typename FloatingPointType,
|
||||
typename std::enable_if<( boost::multiprecision::backends::detail::is_floating_point_or_float128<FloatingPointType>::value == true), bool>::type = true>
|
||||
typename std::enable_if<(boost::multiprecision::backends::detail::is_floating_point_or_float128<FloatingPointType>::value == true), bool>::type = true>
|
||||
FloatingPointType uniform_rand()
|
||||
{
|
||||
return uniform_real<FloatingPointType>();
|
||||
}
|
||||
|
||||
template <typename FloatingPointType>
|
||||
boost::multiprecision::backends::cpp_double_float<typename FloatingPointType::float_type> uniform_rand()
|
||||
template <typename CompositeFloatType,
|
||||
typename std::enable_if<(boost::multiprecision::backends::detail::is_floating_point_or_float128<CompositeFloatType>::value == false), bool>::type = true>
|
||||
CompositeFloatType uniform_rand()
|
||||
{
|
||||
using float_type = typename FloatingPointType::float_type;
|
||||
return boost::multiprecision::backends::cpp_double_float<float_type>(uniform_real<float_type>()) * boost::multiprecision::backends::cpp_double_float<float_type>(uniform_real<float_type>());
|
||||
}
|
||||
using float_type = typename CompositeFloatType::backend_type::float_type;
|
||||
|
||||
return CompositeFloatType(uniform_real<float_type>())
|
||||
* CompositeFloatType(uniform_real<float_type>());
|
||||
}
|
||||
|
||||
template <typename FloatingPointType>
|
||||
typename std::enable_if<( boost::multiprecision::backends::detail::is_floating_point_or_float128<FloatingPointType>::value == true), FloatingPointType>::type
|
||||
@@ -80,37 +82,59 @@ log_rand()
|
||||
if (uniform_real<float>() < (1. / 100.))
|
||||
return 0; // throw in a few zeroes
|
||||
using std::ldexp;
|
||||
using boost::multiprecision::ldexp;
|
||||
FloatingPointType ret = ldexp(uniform_real<FloatingPointType>(), rand_in_range(std::numeric_limits<FloatingPointType>::min_exponent, std::numeric_limits<FloatingPointType>::max_exponent));
|
||||
using std::fmax;
|
||||
return fmax(ret, std::numeric_limits<FloatingPointType>::epsilon());
|
||||
}
|
||||
|
||||
template <typename FloatingPointType>
|
||||
boost::multiprecision::backends::cpp_double_float<typename FloatingPointType::float_type> log_rand()
|
||||
template <typename CompositeFloatType,
|
||||
typename std::enable_if<(boost::multiprecision::backends::detail::is_floating_point_or_float128<CompositeFloatType>::value == false), bool>::type = true>
|
||||
CompositeFloatType log_rand()
|
||||
{
|
||||
boost::multiprecision::backends::cpp_double_float<typename FloatingPointType::float_type> a(uniform_rand<boost::multiprecision::backends::cpp_double_float<typename FloatingPointType::float_type> >() + typename FloatingPointType::float_type(1));
|
||||
a *= log_rand<typename FloatingPointType::float_type>();
|
||||
using float_type = typename CompositeFloatType::backend_type::float_type;
|
||||
|
||||
CompositeFloatType
|
||||
a
|
||||
(
|
||||
uniform_rand<CompositeFloatType>()
|
||||
+ float_type(1)
|
||||
);
|
||||
|
||||
a *= log_rand<float_type>();
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
template <typename ConstructionType, typename FloatingPointType, typename std::enable_if<std::numeric_limits<FloatingPointType>::is_iec559>::type const* = nullptr>
|
||||
ConstructionType construct_from(FloatingPointType f) {
|
||||
ConstructionType construct_from(FloatingPointType f)
|
||||
{
|
||||
return ConstructionType(f);
|
||||
}
|
||||
|
||||
template <typename ConstructionType, typename FloatingPointType, typename std::enable_if<!std::numeric_limits<FloatingPointType>::is_iec559>::type const* = nullptr>
|
||||
ConstructionType construct_from(FloatingPointType f)
|
||||
{
|
||||
return ConstructionType(f.first()) + ConstructionType(f.second());
|
||||
const ConstructionType ct_x(ConstructionType::canonical_value(f).first());
|
||||
const ConstructionType ct_y(ConstructionType::canonical_value(f).second());
|
||||
|
||||
const ConstructionType ct = ct_x + ct_y;
|
||||
|
||||
return ct;
|
||||
}
|
||||
|
||||
template <typename FloatingPointType>
|
||||
bool test_op(char op, const unsigned count = 0x20000U)
|
||||
{
|
||||
using naked_double_float_type = FloatingPointType;
|
||||
using control_float_type = boost::multiprecision::number<boost::multiprecision::cpp_dec_float<std::numeric_limits<naked_double_float_type>::digits10 * 2 + 1>, boost::multiprecision::et_off>;
|
||||
|
||||
const control_float_type MaxError = boost::multiprecision::ldexp(control_float_type(1), -std::numeric_limits<naked_double_float_type>::digits + 1);
|
||||
constexpr int d10 = std::numeric_limits<naked_double_float_type>::digits10 * 2 + 1;
|
||||
|
||||
using control_float_type = boost::multiprecision::number<boost::multiprecision::cpp_dec_float<d10>, boost::multiprecision::et_off>;
|
||||
|
||||
using boost::multiprecision::ldexp;
|
||||
|
||||
const control_float_type MaxError = ldexp(control_float_type(1), -std::numeric_limits<naked_double_float_type>::digits + 1);
|
||||
std::cout << "testing operator" << op << " (accuracy = " << std::numeric_limits<naked_double_float_type>::digits << " bits)...";
|
||||
|
||||
for (unsigned i = 0U; i < count; ++i)
|
||||
@@ -163,12 +187,6 @@ bool test_op(char op, const unsigned count = 0x20000U)
|
||||
std::cerr << std::setprecision(std::numeric_limits<naked_double_float_type>::digits10 + 2);
|
||||
std::cerr << " [FAILED] while performing '" << std::setprecision(100000) << ctrl_a << "' " << op << " '" << ctrl_b << "', got incorrect result: " << (df_c) << std::endl;
|
||||
|
||||
// uncomment for more debugging information (only for cpp_double_float<> type)
|
||||
//std::cerr << "(df_a = " << df_a.get_raw_str() << ", df_b = " << df_b.get_raw_str() << ")" << std::endl;
|
||||
//std::cerr << "expected: " << ctrl_c << std::endl;
|
||||
//std::cerr << "actual : " << ctrl_df_c << " (" << df_c.get_raw_str() << ")" << std::endl;
|
||||
//std::cerr << "error : " << delta << std::endl;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -201,19 +219,11 @@ int main()
|
||||
{
|
||||
bool result_is_ok = true;
|
||||
|
||||
// uncomment to check if tests themselves are correct
|
||||
//result_is_ok &= test_arithmetic_cpp_double_float::test_arithmetic<float>();
|
||||
//result_is_ok &= test_arithmetic_cpp_double_float::test_arithmetic<double>();
|
||||
//result_is_ok &= test_arithmetic_cpp_double_float::test_arithmetic<long double>();
|
||||
result_is_ok &= test_arithmetic_cpp_double_float::test_arithmetic<boost::multiprecision::number<boost::multiprecision::backends::cpp_double_float<float>, boost::multiprecision::et_off>>();
|
||||
result_is_ok &= test_arithmetic_cpp_double_float::test_arithmetic<boost::multiprecision::number<boost::multiprecision::backends::cpp_double_float<double>, boost::multiprecision::et_off>>();
|
||||
result_is_ok &= test_arithmetic_cpp_double_float::test_arithmetic<boost::multiprecision::number<boost::multiprecision::backends::cpp_double_float<long double>, boost::multiprecision::et_off>>();
|
||||
#ifdef BOOST_MATH_USE_FLOAT128
|
||||
//result_is_ok &= test_arithmetic_cpp_double_float::test_arithmetic<boost::multiprecision::float128>();
|
||||
#endif
|
||||
|
||||
result_is_ok &= test_arithmetic_cpp_double_float::test_arithmetic<boost::multiprecision::backends::cpp_double_float<float> >();
|
||||
result_is_ok &= test_arithmetic_cpp_double_float::test_arithmetic<boost::multiprecision::backends::cpp_double_float<double> >();
|
||||
result_is_ok &= test_arithmetic_cpp_double_float::test_arithmetic<boost::multiprecision::backends::cpp_double_float<long double> >();
|
||||
#ifdef BOOST_MATH_USE_FLOAT128
|
||||
result_is_ok &= test_arithmetic_cpp_double_float::test_arithmetic<boost::multiprecision::backends::cpp_double_float<boost::multiprecision::float128> >();
|
||||
//result_is_ok &= test_arithmetic_cpp_double_float::test_arithmetic<boost::multiprecision::backends::cpp_double_float<boost::multiprecision::float128>>();
|
||||
#endif
|
||||
|
||||
return (result_is_ok ? 0 : -1);
|
||||
|
||||
Reference in New Issue
Block a user