2

使用printf及其表亲sprintffprintf显示mpreal-type 变量的值的正确语法是什么?我尝试过将天真的铸造加倍:

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

只是从 g++ 收到此错误消息:

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

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

我听说该类型mpreal是该的一部分,旨在允许使用通常的二元运算符来执行任意精度的算术运算。

4

2 回答 2

6

mpreal任意精度浮点数值类型。

因此,mpreal数字可能具有比double. 这意味着在显示之前四舍五入是没有意义的 mpreal —— double在这种情况下,您将失去所有原始精度。

mpreal在 C++中很容易显示:

/* 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如上面的示例所示。

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

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

于 2012-03-09T01:20:29.693 回答
2

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

于 2012-03-09T00:19:24.363 回答