Включить<Усиление/Многоточность/cpp_bin_float.hpp>
namespace boost{ namespace multiprecision{
enum digit_base_type
{
digit_base_2 = 2,
digit_base_10 = 10
};
template <unsigned Digits, digit_base_type base = digit_base_10, class Allocator = void, class Exponent = int, ExponentMin = 0, ExponentMax = 0>
class cpp_bin_float;
typedef number<cpp_bin_float<50> > cpp_bin_float_50;
typedef number<cpp_bin_float<100> > cpp_bin_float_100;
typedef number<backends::cpp_bin_float<24, backends::digit_base_2, void, boost::int16_t, -126, 127>, et_off> cpp_bin_float_single;
typedef number<backends::cpp_bin_float<53, backends::digit_base_2, void, boost::int16_t, -1022, 1023>, et_off> cpp_bin_float_double;
typedef number<backends::cpp_bin_float<64, backends::digit_base_2, void, boost::int16_t, -16382, 16383>, et_off> cpp_bin_float_double_extended;
typedef number<backends::cpp_bin_float<113, backends::digit_base_2, void, boost::int16_t, -16382, 16383>, et_off> cpp_bin_float_quad;
}}
cpp_bin_float
back-end используется в сочетании сномером
: Он действует как полностью C++ (только заголовк и без зависимостей) тип числа с плавающей запятой, который является заменой для родных типов с плавающей запятой C++, но с гораздо большей точностью.
Типcpp_bin_float
можно использовать с фиксированной точностью, указав ненулевойDigits
шаблонный параметр. Типдефыcpp_bin_float_50
иcpp_bin_float_100
обеспечивают арифметические типы с точностью 50 и 100 десятичных знаков соответственно.
Опционально можно указать, указана ли точность в десятичных цифрах или двоичных битах — например, объявитьcpp_bin_float
с точно такой же точностью, как.двойной
можно использоватьномер<cpp_bin_float<53,digit_base_2>>
. Типдефыcpp_bin_float_single
,cpp_bin_float_double
,cpp_bin_float_quad
иcpp_bin_float_double_extended
обеспечивают программные аналоги IEEE одинарного, двойного и четырехпоплавкового типов данных плюс Intel-расширенный-двойной тип соответственно. Обратите внимание, что хотя эти типы функционально эквивалентны родным типам IEEE, они не имеют такого же размера или раскладки битов, как истинные совместимые типы IEEE.
Обычноcpp_bin_float
не выделяет памяти: все пространство, необходимое для его цифр, выделяется непосредственно внутри класса. В результате следует позаботиться о том, чтобы не использовать класс со слишком высоким количеством цифр, поскольку требования к пространству стека могут выйти из-под контроля. Если это представляет проблему, то предоставление распределителя в качестве параметра шаблона заставляетcpp_bin_float
динамически распределять необходимую ему память: это значительно уменьшает размерcpp_bin_float
и увеличивает жизнеспособный верхний предел на количество цифр за счет производительности. Однако имейте в виду, что арифметические операции быстро становятсяочень дорогимипо мере роста числа цифр: текущая реализация действительно не оптимизирована или не предназначена для больших чисел. Обратите внимание, что поскольку фактический тип выделенных объектов является полностью непрозрачным, было бы предложено использовать распределитель сvoidvalue_type
, например:номер<cpp_bin_float<1000,цифрой_base_10,std::allocator<92]void>>>>>>>[
Конечные параметры шаблона определяют тип и диапазон экспоненты: параметрЭкспонент
может быть любого подписанного целого типа, но обратите внимание, чтоМинэкспонент
иMaxExponent
не может идти прямо до пределовЭкспонент
типа, поскольку для внутренних расчетов должен быть небольшой дополнительный запас хода. Вы получите ошибку времени компиляции, если это так. Кроме того, если MinExponent или MaxExponent равны нулю, то библиотека выберет подходящие значения, максимально большие с учетом ограничений типа и потребности в дополнительном запасе для внутренних расчетов.
Существует полная стандартная библиотека иnumeric_limits
поддержка для этого типа.
Что вы должны знать при использовании этого типа:
- По умолчанию построенные
cpp_bin_float
s имеют значение нуля.
- Радикс этого типа равен 2, даже если точность указана как десятичные цифры.
- Тип поддерживает как бесконечности, так и NaN. Бесконечность генерируется всякий раз, когда результат будет переполнен, и NaN генерируется для любой математически неопределенной операции.
- Есть
std::числовые ограничения
специализация для этого типа.
- Любое
число
, инстанцированное по этому типу, можно конвертировать в любое другоечисло
, инстанцированное по этому типу - например, вы можете конвертировать изчисло<cpp_bin_float<50>>>[ Узкие конверсии округляются до ближайших и являютсяявными
.
- Конверсия из строки приводит к тому, что
std::runtime_error
выбрасывается, если строка не может быть интерпретирована как действительное число с плавающей точкой.
- Все арифметические операции правильно округлены до ближайшего. Конверсии струн и функция
sqrt
также правильно округлены, но трансцендентные функции (грех, кос, поу, экс и т. д.) не являются.
#include <boost/multiprecision/cpp_bin_float.hpp>
#include <boost/math/special_functions/gamma.hpp>
#include <iostream>
int main()
{
using namespace boost::multiprecision;
cpp_bin_float_100 b = 2;
std::cout << std::numeric_limits<cpp_bin_float_100>::digits << std::endl;
std::cout << std::numeric_limits<cpp_bin_float_100>::digits10 << std::endl;
std::cout << std::setprecision(std::numeric_limits<cpp_bin_float_100>::max_digits10)
<< log(b) << std::endl;
std::cout << boost::math::tgamma(b) << std::endl;
std::cout << boost::math::tgamma(b * b) << std::endl;
std::cout << boost::math::tgamma(cpp_bin_float_100(1000)) << std::endl;
return 0;
}