如何将printf与mpfr和mpreal一起使用

How to use printf with mpfr and mpreal

本文关键字:mpreal 一起 mpfr printf      更新时间:2023-10-16

使用printf及其表亲sprintffprintf来显示mpreal类型变量的值的正确语法是什么?我试过天真的选角来加倍:

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

只接收来自g++的错误消息:

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

我在程序的其他地方使用double类型的变量没有问题。

我听说mpreal类型是这个库的一部分,它旨在使用常用的二进制运算符来执行任意精度的算术运算。

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 = %sn", pi.toString().c_str());         
/* Custom format, 60 digits */
printf("pi = %sn", pi.toString("%.60RNf").c_str());
/* Using native printf from MPFR*/
mpfr_printf("pi = %.60RNfn", pi.mpfr_srcptr());

多精度数字的格式规范与标准的格式规范相同,但舍入规范除外。您可以安全地使用四舍五入到最接近的RN,如上面的示例所示。

MPFR文档中提供了有关mp格式的更多详细信息。

(我是mpreal类(又名MPFR C++)的作者

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()成员函数打印全精度。