精确地将double转换为mpf_class

时间:2012-12-01 19:55:58

标签: c++ gmp

从double初始化GMP浮点变量(mpf_t或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作为迭代数值方法,因此这些非零引入错误并使方法收敛缓慢。

如果我将m初始化为mpf_class m("0.1");,则输出为:

1.00000000000000000000000000000000000000000000000000e-01

问题不在于operator<<的{​​{1}}重载。问题不仅存在于初始化,也存在于分配中。

目前我使用以下内容:

mpf_class

正确转换。

是否有更快和/或更原生的方式来做它?

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

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:-1)

您可以使用此方法

mpf_class a; double d=0.1; a=static_cast<mpf_class>(d*10)/static_cast<mpf_class>(10); 如果您知道双精度数有多少小数位,可以使用此方法