精确地将双倍转换为mpf_class

Convert double to mpf_class precisely

本文关键字:mpf class 转换      更新时间:2023-10-16

从双精度初始化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<< mpf_class过载.问题不仅存在于初始化方面,还存在于分配方面。

目前我使用以下方法:

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

用于正确转换。

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

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

如果你以同样的精度打印出双精度,你应该看到同样奇怪的数字。这仅仅是因为 0.1 不能准确地用浮点数表示。mpf_class准确地再现了存储在双精度中的值。这是不符合您期望的双倍。

可能有一种方法可以指定 gmp 的精度或某种方式对输入进行舍入。不过我不确定去哪里看

编辑

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

您可以使用

此方法

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