<#include<boost/multiprecision/mpfr.hpp>>
namespace boost{ namespace multiprecision{
enum mpfr_allocation_type
{
   allocate_stack,
   allocate_dynamic
};
template <unsigned Digits10, mpfr_allocation_type AllocateType = allocate_dynamic>
class mpfr_float_backend;
typedef number<mpfr_float_backend<50> >    mpfr_float_50;
typedef number<mpfr_float_backend<100> >   mpfr_float_100;
typedef number<mpfr_float_backend<500> >   mpfr_float_500;
typedef number<mpfr_float_backend<1000> >  mpfr_float_1000;
typedef number<mpfr_float_backend<0> >     mpfr_float;
typedef number<mpfr_float_backend<50, allocate_stack> >    static_mpfr_float_50;
typedef number<mpfr_float_backend<100, allocate_stack> >   static_mpfr_float_100;
}} 
<mpfr_float_backend>используется совместно с<number>: Он действует как тонкая обертка вокругMPFR<mpfr_t>, чтобы обеспечить тип реального числа, который является заменой для нативных типов плавающих точек C++, но с гораздо большей точностью.
Тип<mpfr_float_backend>можно использовать с фиксированной точностью, указав ненулевой<Digits10>параметр шаблона, или с переменной точностью, установив аргумент шаблона до нуля. Типдефы mpfr_float_50, mpfr_float_100, mpfr_float_500, mpfr_float_1000 обеспечивают арифметические типы с точностью 50, 100, 500 и 1000 десятичных знаков соответственно. Typedef mpfr_float обеспечивает переменный тип точности, точность которого может управляться через функции<number>.
Кроме того, второй параметр шаблона позволяет выбирать между динамическим распределением (по умолчанию и использует обычные процедуры распределения MPFR) или распределением стека (где вся память, необходимая для базовых типов данных, хранится в<mpfr_float_backend>). Последний вариант может привести к значительно более быстрому кодированию за счет увеличения размера<mpfr_float_backend>. Он может использоваться только с фиксированной точностью и должен использоваться только для более низких цифр. Обратите внимание, что мы не можем гарантировать, что использование<allocate_stack>не вызовет каких-либо вызовов для процедур распределения mpfr, поскольку mpfr может вызывать их внутри своего собственного кода. Следующая таблица дает представление о компромиссе производительности при 50 десятичных цифрах точности:
| ![[Note]](/img/note.png) | Note | 
| Этот тип обеспечивает поддержку<numeric_limits>только тогда, когда точность фиксируется во время компиляции. | 
Как и обычные преобразования из арифметических и струнных типов, экземпляры<number<mpfr_float_backend<N>>>являются копируемыми и присваиваемыми из:
- GMPродные типы<mpf_t>,<mpz_t>,<mpq_t>.
- MPFRнативный тип<mpfr_t>.
- <number>обертывается вокруг этих типов:<number<mpfr_float_backend<M>>>,<number<mpf_float<M>>>,<number<gmp_int>>,<number<gmp_rational>>.
Также можно получить доступ к базовому<mpfr_t>через функцию<mpfr_float_backend>элемента данных.
Что вы должны знать при использовании этого типа:
- По умолчанию<mpfr_float_backend>устанавливается на NaN (это поведение по умолчаниюMPFR).
- Все операции проходят в обход ближайших.
- Не вносятся изменения вGMPилиMPFRглобальные настройки, поэтому этот тип может сосуществовать с существующимMPFRилиGMPкодом.
- Код может в равной степени использоватьMPIRвместоGMP— действительно, это предпочтительный вариант на Win32.
- Этот бэкэнд поддерживает rvalue-ссылки и является Move-Aware, делая выводы<number>об этом бэкэнд-движении осведомленными.
- Преобразование из строки приводит к тому, что<std::runtime_error>выбрасывается, если строка не может быть интерпретирована как действительное число с плавающей точкой.
- Разделение на ноль приводит к бесконечности.
#include <boost/multiprecision/mpfr.hpp>
#include <boost/math/special_functions/gamma.hpp>
#include <iostream>
int main()
{
   using namespace boost::multiprecision;
   
   mpfr_float a = 2;
   mpfr_float::default_precision(1000);
   std::cout << mpfr_float::default_precision() << std::endl;
   std::cout << sqrt(a) << std::endl; 
   
   mpfr_float_100 b = 2;
   std::cout << std::numeric_limits<mpfr_float_100>::digits << std::endl;
   
   std::cout << log(b) << std::endl; 
   
   std::cout << boost::math::tgamma(b) << std::endl;
   
   std::cout << boost::math::tgamma(b * b) << std::endl;
   
   mpfr_t r;
   mpfr_init(r);
   mpfr_set(r, b.backend().data(), GMP_RNDN);
   mpfr_clear(r);
   return 0;
}