GMP mpf_class 精度低于预期?

GMP mpf_class precision lower than expected?

我正在尝试测试 GMP 是否以我想要的精度与下一个程序一起工作:

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


int main()                                                                                                                                            
{                                                                                                                                                     
    long prec = 1000;                                                                                                                                 
    mpf_set_default_prec(prec);                                                                                                                       

    mpf_class a(1);                                                                                                                                   
    mpf_class b(mpf_class(1)/sqrt(mpf_class(2)));                                                                                                     
    mpf_class t(mpf_class(1)/mpf_class(4));                                                                                                           
    mpf_class p(1);                                                                                                                                   
    mpf_class x,y,pi, pi2, sub;                                                                                                                       
    pi2 = mpf_class(3.141592653589793238462643383279502884197169399375105820974944592307816406286);                                                   

    while ( a - b > mpf_class(1e-250))                                                                                                                
    {                                                                                                                                                 
        x = (a + b)/2;                                                                                                                                
        y = sqrt(a*b);                                                                                                                                
        t = t - p*(a-x)*(a-x);                                                                                                                        
        a = x;                                                                                                                                        
        b = y;                                                                                                                                        
        p *=2;                                                                                                                                        
    }                                                                                                                                                 

    pi =  (a+b)*(a+b)/(mpf_class(4)*t);                                                                                                               

    sub = pi - pi2;                                                                                                                                   
    std::cout << std::setprecision(80) << pi << '\n' << pi2 << '\n' << sub << '\n';                                                              

    return 0;                                                                                                                                         
}

它计算了很多位的圆周率,然后从pi中减去pi2(100位的圆周率)(计算的值,很容易检查显示的所有小数是否正确)。

输出:

3.141592653589793238462643383279502884197169399375105820974944592307816406286209
3.141592653589793115997963468544185161590576171875
1.2246467991473531772260659322750010582097494459230781640628620899862803482534212e-16

问题是 pi2 只能使用小数点后 16 位,我不知道为什么。

代码取自http://ubuntuforums.org/showthread.php?t=459229

我尝试了不同的启动方式pi2,但我无法获得超过 16 位数字。

使用 std::string 而不是数字文字。 aaa.bbb 格式的任何值都被视为双精度(有限精度),并带有 f 后缀的浮点数(再次是有限精度)。在您的情况下,它可能被视为双倍。

const std::string number = "3.141592653589793238462643383279502884197169399375105820974944592307816406286";
mpz_class pi2(number);