是否可以使用gmp打印浮点数的大量数字?

时间:2014-10-17 16:09:39

标签: floating-point precision gmp

我想打印

1589128402970546000515214676475308953824987995059891920501615931630880

numbers of decimal expansion of ratio

33877456965431938318210482471113262183356704085033125021829876006886584214655562/237142198758023568227473377297792835283496928595231875152809132048206089502588927

我尝试使用gmp库:

// gcc p.c -lgmp

#include <stdio.h>
#include <gmp.h>

int main (int argc, char **argv)
{       



     mpf_set_default_prec(1024); // set default precision in bits


    // declare   
    mpz_t zn;
    mpz_t zd;
    mpq_t q;
    mpf_t fn;
    mpf_t fd; 
    mpf_t f; // f=float(q=n/d)

    // init
    mpz_init (zn);
    mpz_init (zd);
    mpq_init (q);
    mpf_init2 (fn, 794564201485273000257607338237654476912493997529945960250807965815440 ); 
    mpf_init (fd); 
    mpf_init (f); 

    // set
    mpz_set_str(zn, "33877456965431938318210482471113262183356704085033125021829876006886584214655562", 10 ); // 
    // mpz_set_ui(n,33877456965431938318210482471113262183356704085033125021829876006886584214655562);   warning: integer constant is too large for its type [enabled by default]
    mpz_set_str(zd, "237142198758023568227473377297792835283496928595231875152809132048206089502588927", 10);
    mpq_set_str(q, "33877456965431938318210482471113262183356704085033125021829876006886584214655562/237142198758023568227473377297792835283496928595231875152809132048206089502588927", 10);

    mpf_set_z(fn, zn);
    mpf_set_z(fd, zd);



    //
    mpf_div(f, fn, fd);

    // print result 
    gmp_printf ("  decimal floating point number : %.Ff \n", f); //

    // clear  
    mpz_clear (zn);
    mpz_clear (zd);
    mpq_clear(q);
    mpf_clear (fn);
    mpf_clear (fd);
    mpf_clear (f);

    return 0;

}

但结果只有22位十进制数字:

十进制浮点数:0.142857142857142857143

我该怎么做?

2 个答案:

答案 0 :(得分:2)

您需要提高精度(即尾数位)才能获得更多的十进制数字。正如GMP documentation所述(强调我的):

  

每个浮点数的尾数都有用户可选择的精度,有限   只有可用的内存。每个变量都有自己的精度,和   可以随时增加或减少。

默认情况下,它为尾数选择64位,基本上你得到的是:

dig10 = floor(dig2/log2(10))

因此,您在开头只有大约19个有效的十进制数字。通过要求更高的精确度,您只需获得更多精确度:

#include <stdio.h>
#include <gmp.h>

int main(void)
{
    mpz_t zn, zd;
    mpf_t fn, fd, f;

    mpf_set_default_prec(1024);

    mpz_init_set_str(zn, "33877456965431938318210482471113262183356704085033125021829876006886584214655562", 10);
    mpz_init_set_str(zd, "237142198758023568227473377297792835283496928595231875152809132048206089502588927", 10);

    mpf_init(fn); mpf_init(fd); mpf_init(f);

    mpf_set_z(fn, zn);
    mpf_set_z(fd, zd);

    mpf_div(f, fn, fd);

    gmp_printf ("decimal floating point number: %.Ff\n", f);

    return 0;
}

结果:

decimal floating point number: 0.1428571428571428571428571428571428571428571428571428571428571428571428571428571470740220344350664325965724776508647459411274100902601628882480671861148592450467118250772869175909603098316903937670228712738977340379914830920623570643668473851880233962854802649343258544237378422095661611829666642751471587447213

如果你想要一些固定数量的十进制数字(假设zn/zd商为零),只需使用上面(或更复杂的)对数方程。

答案 1 :(得分:0)

// gcc p.c -lgmp

#include <stdio.h>
#include <gmp.h>

int main (int argc, char **argv)
{       



     mpf_set_default_prec(100024); // set default precision in bits


    // declare   
    mpz_t zn;
    mpz_t zd;
    mpq_t q;
    mpf_t fn;
    mpf_t fd; 
    mpf_t f; // f=float(q=n/d)

    // init
    mpz_init (zn);
    mpz_init (zd);
    mpq_init (q);
    mpf_init (fn) ; //794564201485273000257607338237654476912493997529945960250807965815440 ,100); 
    mpf_init (fd); 
    mpf_init (f); 

    // set
    mpz_set_str(zn, "33877456965431938318210482471113262183356704085033125021829876006886584214655562", 10 ); // 
    // mpz_set_ui(n,33877456965431938318210482471113262183356704085033125021829876006886584214655562);   warning: integer constant is too large for its type [enabled by default]
    mpz_set_str(zd, "237142198758023568227473377297792835283496928595231875152809132048206089502588927", 10);
    //mpq_set_str(q, "33877456965431938318210482471113262183356704085033125021829876006886584214655562/237142198758023568227473377297792835283496928595231875152809132048206089502588927", 10);

    mpf_set_z(fn, zn);
    mpf_set_z(fd, zd);



    //
    mpf_div(f, fn, fd);

    // print result 
    printf (" ratio =  "); mpz_out_str(stdout, 10,zn);  printf (" / ");     mpz_out_str(stdout, 10,zd);  printf (" \n "); 
    gmp_printf ("  decimal floating point number : %.Ff \n", f); //

    // clear  
    mpz_clear (zn);
    mpz_clear (zd);
    mpq_clear(q);
    mpf_clear (fn);
    mpf_clear (fd);
    mpf_clear (f);

    return 0;

}

上面的代码更好,但如果我需要n个十进制数字,我应该将精度设置为n * 4?

编辑:

  

我想打印1589128402970546000515214676475308953824987995059891920501615931630880数字......

这根本不可能,因为它是10 ^ 71个数字,而不是all books in the world中的字符(字母)(10 ^ 8本书x 10^5 chars per book