Как отмечается в документации Boost.Multiprecision, определенные конструкции программ не будут компилироваться при использовании шаблонов выражения. Одним из примеров, с которым могут столкнуться многие пользователи, является Boost. Тест (1.54 и более ранний) при использовании макроса BOOST_CHECK_CLOSE и BOOST_CHECK_CLOSE_FRACTION.
Если, например, вы хотите использовать любой тип многоточности, такой как cpp_dec_float_50
вместо double
, чтобы обеспечить большую точность, вам нужно будет переопределить по умолчанию boost::::et_on
с boost::multiprecision::et_off
.
#include <boost/multiprecision/cpp_dec_float.hpp>
Для определения типа 50 десятичных цифр с использованием cpp_dec_float
необходимо передать два параметра шаблона boost::multiprecision::number
.
Может быть более разборчивым использовать двухступенчатое определение типа, такое как:
typedef boost::multiprecision::cpp_dec_float<50> mp_backend;
typedef boost::multiprecision::number<mp_backend, boost::multiprecision::et_off> cpp_dec_float_50_noet;
Здесь мы сначала определяем mp_backend
как cpp_dec_float
с 50 цифрами. На втором шаге этот бэкэнд переходит к boost::множество ::число
с boost::многообразие::et_off
, перечисленный тип.
typedef boost::multiprecision::number<boost::multiprecision::cpp_dec_float<50>, boost::multiprecision::et_off>
cpp_dec_float_50_noet;
Вы можете уменьшить типизацию с помощью директивы
, используя namespace boost::multiprecision;
при желании, как показано ниже.
using namespace boost::multiprecision;
Теперь cpp_dec_float_50_noet
или cpp_dec_float_50_et
можно использовать в качестве прямой замены встроенных типов, таких как double
и т.д.
BOOST_AUTO_TEST_CASE(cpp_float_test_check_close_noet)
{
typedef number<cpp_dec_float<50>, et_off> cpp_dec_float_50_noet;
std::cout.precision(std::numeric_limits<cpp_dec_float_50_noet>::digits10);
std::cout << std::showpoint << std::endl;
cpp_dec_float_50_noet a ("1.0");
cpp_dec_float_50_noet b ("1.0");
b += std::numeric_limits<cpp_dec_float_50_noet>::epsilon();
cpp_dec_float_50_noet eps = std::numeric_limits<cpp_dec_float_50_noet>::epsilon();
std::cout <<"a = " << a << ",\nb = " << b << ",\neps = " << eps << std::endl;
BOOST_CHECK_CLOSE(a, b, eps * 100);
BOOST_CHECK_CLOSE_FRACTION(a, b, eps);
}
BOOST_AUTO_TEST_CASE(cpp_float_test_check_close_et)
{
typedef number<cpp_dec_float<50>, et_on> cpp_dec_float_50_et;
std::cout.precision(std::numeric_limits<cpp_dec_float_50_et>::digits10);
std::cout << std::showpoint << std::endl;
cpp_dec_float_50_et a("1.0");
cpp_dec_float_50_et b("1.0");
b += std::numeric_limits<cpp_dec_float_50_et>::epsilon();
cpp_dec_float_50_et eps = std::numeric_limits<cpp_dec_float_50_et>::epsilon();
std::cout << "a = " << a << ",\nb = " << b << ",\neps = " << eps << std::endl;
BOOST_CHECK_CLOSE(a, b, eps * 100);
BOOST_CHECK_CLOSE_FRACTION(a, b, eps);
Используя cpp_dec_float_50
с включенным использованием шаблона выражения по умолчанию, сообщение об ошибке компилятора для 'BOOST_CHECK_CLOSE_FRACTION(a, b, eps); будет:
Полный пример кода находится на test_cpp_float_close_fraction.cpp