找回密码
 欢迎注册
楼主: medie2005

[讨论] 阶乘和圆周率

  [复制链接]
发表于 2008-12-8 10:37:00 | 显示全部楼层
回复29楼,那是很久以前的事了,代码不好找了。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-12-8 14:43:57 | 显示全部楼层
#include #include #include #define DefaultBitLength 128 int main(void) { mpfr_t a, b, low, hi, lf, t; double dLow, dHi, dLf, dA; int find = 0; long i = 0; mpfr_init2(a, DefaultBitLength); mpfr_set_d(a, 2.0, GMP_RNDD); mpfr_init2(b, DefaultBitLength); mpfr_set_d(b, 1.0, GMP_RNDD); mpfr_init2(low, DefaultBitLength); mpfr_init2(hi, DefaultBitLength); mpfr_init2(lf, DefaultBitLength); mpfr_set_d(lf, 0.0, GMP_RNDD); mpfr_init2(t, DefaultBitLength); printf("请输入上界: "); scanf("%lf", &dHi); printf("请输入下界: "); scanf("%lf", &dLow); // printf("当前界限[%f, %f]\n", dLow, dHi); mpfr_set_d(low, dLow, GMP_RNDD); mpfr_set_d(hi, dHi, GMP_RNDD); mpfr_log10(low, low, GMP_RNDD); mpfr_log10(hi, hi, GMP_RNDD); while (1) { mpfr_log10(t, a, GMP_RNDD); mpfr_add(lf, lf, t, GMP_RNDD); if (mpfr_cmp_d(lf, 1.0) >= 0) mpfr_sub_ui(lf, lf, 1, GMP_RNDD); if ((mpfr_cmp(lf, low) >= 0) && (mpfr_cmp(lf, hi) < 0)) { find = 1; break; } mpfr_add(a, a, b, GMP_RNDD); if (mpfr_cmp_d(a, 10.0) >= 0) { i++; mpfr_div_ui(b, b, 10, GMP_RNDD); mpfr_add_ui(a, b, 1, GMP_RNDD); } } if (find) { dLf = mpfr_get_d1(lf); while (i > 0) { mpfr_mul_ui(a, a, 10, GMP_RNDD); i--; } dA = mpfr_get_d1(a); printf("当前界限下的阶乘%.0f!, 对应的对数%.15f", dA, dLf); } mpfr_clear(a); mpfr_clear(b); mpfr_clear(low); mpfr_clear(hi); mpfr_clear(lf); mpfr_clear(t); return 1; } //////////////////////////////////////////////////////// 利用mpfr可写出适合超过100000000的阶乘的一个寻找程序 但似乎速度慢很多哦
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-12-8 16:47:37 | 显示全部楼层
使用这个库之后 速度巨慢了 上次的程序,十几分钟就能计算出 314159265的结果
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-12-9 08:30:29 | 显示全部楼层
经过一夜的运算找到了 起始数字314159265的结果 在20# 用PARI计算的0.497149872468489(程序输出的,转换为Double, 真实的是96Bit浮点)对应的数字 希望有人进行复检 另外,下个数字运算程序可能就要写定时状态保存了,而且要用128位浮点了 唯一的好处是这个程序基本是线性时间
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-12-9 08:43:53 | 显示全部楼层
没有问题,我用striling公式带入windows计算器验算了一下,结果为: 3.14159265196... 而Windows计算机浮点精度挺高的。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-12-9 08:48:48 | 显示全部楼层
32#程序是在MinGW+ GCC4.21下编译通过的 预先编译了GMP 4.2.4和MPFR2.3.2,均是静态库形式 gcc factPi.c -std=c99 -O2 -lmpfr -lgmp -o factPi.exe 编译 可脱离MinGW运行 有兴趣的童鞋 我可以上传一个包 覆盖在MINGW的 include和lib就能使用
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-12-9 08:56:16 | 显示全部楼层
.h放mingw\include 其他放 mingw\lib 安装msys进入模拟unix环境gcc编译 GMP-MPFR-MinGW-static.rar (433.45 KB, 下载次数: 0)
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-12-9 13:51:57 | 显示全部楼层
在把浮点数保存在文件里时遇到困难 不知道如何写 MPFR这方面的资料太少了 mpfr_out_str不能用 mpfr_get_str怎么不能保存小数点?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-12-15 19:31:22 | 显示全部楼层
今天想到一个新思路 计算了 log(3.141592653590) = 0.4971498726941624371131490186099 log(3.141592653589) = 0.49714987268172081667353310595166 二者的差是1.3824022710488533020286478680411e-13 约等于2^(-42.717887740820254037211382936331 ) 考虑double的精度是2^(-53) 显然只要最终数字的精度大于2^(-43)即可 那么如果我们用MPFR每隔1024隔数字 用strling公式 计算一个精度在2^(-53)的准确的阶乘的log值 而之间的数字则使用double类型的log进行连加 则中间状态的精度肯定大于2^(-43) =========================== 为了防止边界溢出现象 我们可以考虑使用long double类型 则此时的机器精度是2^(-63)
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-12-15 19:36:20 | 显示全部楼层
在long double情况下 有 Prelude> let a = 3.14159265358979 Prelude> let b = 3.14159265358980 Prelude> log(b) / log(10) - log(a) / log(10) 1.4432899320127035e-15 Prelude> log(it) / log(2) -49.29956028185891 Prelude> it + 10 -59.29956028185891 即保守估计可以计算到314159265358979
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

小黑屋|手机版|数学研发网 ( 苏ICP备07505100号 )

GMT+8, 2024-12-22 10:01 , Processed in 0.026371 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表