2012-03-08 94 views
2

使用printf及其亲戚sprintffprintf显示mpreal-类型变量的值的正确语法是什么?我曾尝试天真铸造双:如何在mpfr和mpreal中使用printf

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

只从G ++收到此错误信息:

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

我不得不使用double型变量别处上的程序没有问题。

我听说mpreal作为library的一部分,旨在使普通的二元运算符能够执行任意精度的算术运算。

+0

你接受了[我的答案](http://stackoverflow.com/a/9627136/827263),但[帕维尔的答案](HTTP:// stackoverflow.com/a/9627660/827263)可能会更好(请参阅我的更新)。 – 2013-11-01 01:26:30

回答

6

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

因此,mpreal数字可能比double有更多的有效数字(甚至数百或千分之一)。这意味着它是毫无意义的回合mprealdouble显示之前 - 你将失去在这种情况下的所有原始准确性。

这是很容易在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 documentation

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

+0

嗨,感谢您的伟大图书馆:)工作真的很棒!我想问一个关于答案的简单问题,没有参数toString()仍然给我数字与科学表达式(即; e + 16)为大数,我发现唯一的解决方法是与像toString(“%1024.1024RNf “),确保打印所有数字。你知道一个更好的方法,以防止在例子中打印前导0。 (我的需要是简单地将数字保存到数据库中,让其他程序像字符串一样读取它) – yagmoth555 2016-05-03 15:05:49

+1

不带参数toString()将数字转换为字符串,数字足以将其从生成的字符串恢复,而不会损失准确性。在使用mpreal/MPFR之前不要忘记设置默认精度:mpfr :: mpreal :: set_default_prec() – 2016-05-04 02:18:13

1

mpreal是一类,而不是一个数字型,并且它不以数字类型提供转换运算符。

但它确实提供了进行类型转换的成员函数:

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

所以这应该工作:

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

或:

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

(我还没有证实这)

UPDATE:

一种mpreal对象表示可具有大得多的范围和/或精确度比可以表示为实数的任何内置数字型(这是MPFR整点)。只有当值在该类型的范围内时,转换为数字类型才有意义,并且您不关心额外的精度。

在某些情况下,这可能是不够好,但作为this answer说,你就可以利用重载<<运营商或toString()成员函数打印完整的精度。