#включает </мультиплексия/cpp_dec_floathpp>
namespace boost{ namespace multiprecision{
template <unsigned Digits10, class ExponentType = boost::int32_t, class Allocator = void>
class cpp_dec_float;
typedef number<cpp_dec_float<50> > cpp_dec_float_50;
typedef number<cpp_dec_float<100> > cpp_dec_float_100;
}}
cpp_dec_float
back-end используется в сочетании с number
: он действует как полностью C++ (только заголовк и без зависимостей) тип числа с плавающей точкой, который является заменой для родных типов с плавающей точкой C++, но с гораздо большей точностью.
Тип cpp_dec_float
можно использовать с фиксированной точностью, указав ненулевой Digits10
параметр шаблона. Типдефы cpp_dec_float_50
и cpp_dec_float_100
обеспечивают арифметические типы с точностью 50 и 100 десятичных знаков соответственно. Необязательно, вы можете указать целочисленный тип для использования для экспоненты, это по умолчанию для 32-битного целочисленного типа, который более чем достаточно велик для подавляющего большинства случаев использования, но более крупные типы, такие как long long
, также могут быть указаны, если вам нужен действительно огромный диапазон экспонент. В любом случае ExponentType должен быть встроенным в подписанный целочисленный тип шириной не менее 2 байт и 16 бит.
Обычно cpp_dec_float
не выделяет памяти: все пространство, необходимое для его цифр, выделяется непосредственно внутри класса. В результате следует позаботиться о том, чтобы не использовать класс со слишком высоким количеством цифр, поскольку требования к пространству стека могут выйти из-под контроля. Если это представляет проблему, то предоставление распределителя в качестве конечного параметра шаблона приводит к тому, что cpp_dec_float
динамически распределяет необходимую ему память: это значительно уменьшает размер cpp_dec_float
и увеличивает жизнеспособный верхний предел на количество цифр за счет производительности. Однако имейте в виду, что арифметические операции быстро становятся очень дорогими по мере роста числа цифр: текущая реализация действительно не оптимизирована или не предназначена для больших чисел.
Для этого типа доступна полная стандартная библиотека и поддержка numeric_limits
.
Что вы должны знать при использовании этого типа:
- По умолчанию построенные
cpp_dec_float
s имеют значение нуля.
- Радикс этого типа составляет 10. В результате он может вести себя несколько иначе, чем базовые 2 типа.
- Тип имеет ряд внутренних защитных цифр над и над теми, которые указаны в аргументе шаблона. Обычно они не должны быть видны пользователю.
- Тип поддерживает как бесконечности, так и NaN. Бесконечность генерируется всякий раз, когда результат будет переполнен, и NaN генерируется для любой математически неопределенной операции.
- Для этого типа существует специализация
std::numeric_limits
.
- Любое
число
число , полученное на этом типе, можно конвертировать в любое другое число <cpp_dec_float<50> > cpp_dec_float< >>>>>>><2 Узкие конверсии усечены и эксплицитно
.
- Преобразование из строки приводит к тому, что
std::runtime_error
выбрасывается, если строка не может быть интерпретирована как действительное число с плавающей точкой.
- Фактическая точность
cpp_dec_float
всегда немного выше, чем число цифр, указанных в параметре шаблона, фактически, насколько выше деталь реализации, но всегда по меньшей мере 8 десятичных цифр.
- Операции с участием
cpp_dec_float
всегда усечены. Однако обратите внимание, что, поскольку они являются защитными цифрами, на практике это не оказывает реального влияния на точность в большинстве случаев использования.
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <boost/math/special_functions/gamma.hpp>
#include <iostream>
int main()
{
using namespace boost::multiprecision;
cpp_dec_float_100 b = 2;
std::cout << std::numeric_limits<cpp_dec_float_100>::digits << std::endl;
std::cout << std::numeric_limits<cpp_dec_float_100>::digits10 << std::endl;
std::cout << std::setprecision(std::numeric_limits<cpp_dec_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_dec_float_100(1000)) << std::endl;
return 0;
}