Как использовать printf с mpfr и mpreal - PullRequest
2 голосов
/ 09 марта 2012

Каков правильный синтаксис для использования printf и его двоюродных братьев sprintf и fprintf для отображения значения переменных mpreal -типа?Я пробовал наивное приведение к удвоению:

printf ("... %g ...", (double) var);

только для получения этого сообщения об ошибке от g ++:

error: invalid cast from type ‘mpfr::mpreal’ to type ‘double’

У меня не было проблем с использованием переменных типа double в других местахprogram.

Я слышал о типе mpreal как части этой библиотеки , предназначенной для обеспечения возможности использования обычных двоичных операторов для выполнения арифметических операций произвольной точности.

Ответы [ 2 ]

6 голосов
/ 09 марта 2012

mpreal - числовой тип с плавающей точкой произвольной точности.

Таким образом, mpreal числа могут иметь гораздо более значимые цифры (даже сотни или тысячные), чем double. Это означает, что бессмысленно округлять mpreal до double до отображения - в этом случае вы потеряете всю первоначальную точность.

В C ++ легко отобразить mpreal:

/* 100-digits accurate pi */
mpreal pi = mpfr::const_pi(mpfr::digits2bits(100));

/* Show 60-digits of pi */
cout.precision(60);
cout << pi;

Однако вы также можете использовать его с printf (преобразовав сначала в строку):

/* Display all digits (default formatting) */
printf("pi = %s\n", pi.toString().c_str());         

/* Custom format, 60 digits */
printf("pi = %s\n", pi.toString("%.60RNf").c_str());

/* Using native printf from MPFR*/
mpfr_printf("pi = %.60RNf\n", pi.mpfr_srcptr());

Спецификация формата для чисел с множественной точностью такая же, как и для стандарта, за исключением спецификации округления. Вы можете безопасно использовать округление до ближайшего, RN, как в примерах выше.

Более подробная информация о форматировании mp приведена в Документация MPFR .

(я автор mpreal класс, он же MPFR C ++ )

2 голосов
/ 09 марта 2012

mpreal - это класс, а не числовой тип, и он не предоставляет операторов преобразования в числовые типы.

Но он предоставляет функции-члены, которые выполняют преобразования типов:

long            toLong()    const;
unsigned long   toULong()   const;
double          toDouble()  const;
long double     toLDouble() const;

Так что это должно работать:

printf ("... %g ...", var.toDouble());

или

printf ("... %Lg ...", var.toLDouble());

(Я не подтвердил это.)

ОБНОВЛЕНИЕ:

Объект mpreal представляет действительное число, которое может иметь гораздо больший диапазон и / или точность, чем может быть представлен любым встроенным числовым типом (в этом вся суть MPFR). Преобразование в числовой тип имеет смысл, только если значение находится в пределах диапазона этого типа, и вам не нужна дополнительная точность.

В некоторых случаях этого может быть достаточно, но, как говорит в этом ответе , вы можете печатать с полной точностью, используя либо перегруженный оператор <<, либо функцию-член toString().

...