2012-12-01 89 views
1

从double中初始化GMP浮点变量(mpf_t或mpf_class,无所谓)的正确方法是什么?精确地将double转换为mpf_class

代码:

#include <iostream> 
#include <gmpxx.h> 

int main() 
{ 
     double d=0.1; 

     //1024 bits is more that 300 decimal digits 
     mpf_set_default_prec(1024); 

     mpf_class m(d); 

     //after initializing mpf_class variable, set default output precision 
     std::cout.precision(50); 
     std::cout.setf(std::ios_base::scientific); 

     std::cout << m << std::endl; 

     return 0; 
} 

输出是:

1.00000000000000005551115123125782702118158340454102e-01 

它会好起来的,如果我直接打印d,但在尾数的m变量300个十进制数字是值得信赖的!我将GMP用于迭代数值方法,因此这些非零引入错误并使得方法收敛缓慢。

如果我用来初始化mmpf_class m("0.1");,输出为:

1.00000000000000000000000000000000000000000000000000e-01 

所以问题不在operator<<过载mpf_class。问题不仅存在于初始化中,而且也存在于分配中。

目前我使用以下命令:

mpf_class linsys::DtoGMP(const double& arg) 
{ 
     char buf[512]; 
     sprintf(buf,"%.15le\n",arg); 
     return mpf_class(buf); 
} 

正确转换。

有没有更快和/或更原生的方法来做到这一点?

我的操作系统是的OpenSUSE 12.1,编译器:GCC 4.6.2

回答

2

如果你打印出双与相同的精度,你应该看到相同的奇怪的号码。这只是因为0.1 can't be accurately represented in floating point。 mpf_class正确地重现了存储在double中的值。这是双倍的,不符合你的期望。

可能有一种方法可以指定gmp的精度或某种方法来舍入输入。 我不确定在哪里看

编辑

mpf_class具有精度参数的构造函数:http://www.gnu.org/software/gmp/manual/html_node/C---Interface-Floats.html

+0

这是可以理解的。但是我有很多从GMP到GMP的转换,并带有'DtoGMP'功能。我认为,这不是最快的变体。 – Sergey

+0

这个构造函数不适合我,因为尾数存储在长整型数组中,所以精度不能小于64位(sizeof长int整型)。即使我将精度设置为1,实际精度将为64,因此大约4个错误的数字将被添加到mpf_class变量。 – Sergey