1

从 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 用于迭代数值方法,因此这些非零值会引入错误并使方法收敛缓慢。

如果我初始化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

4

2 回答 2

2

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

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

编辑

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

于 2012-12-01T20:11:47.617 回答
-1

你可以使用这个方法

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

于 2020-01-09T23:12:12.960 回答