|
|

楼主 |
发表于 2003-10-29 19:16:21
|
显示全部楼层
谢谢lordbyorn
不过你提供的函数还是没法满足我所要的精度。
这时由c语言原始数据类型精度限制的。
我使用了gmp库,可以达到很高的精度了,起码小数点后几十位是没问题的。而且很容易扩充成更高精度的。
- #include<stdio.h>
- #include<gmp.h>
- #include<stdlib.h>
- #define PREC 328
- void normal_cdf(mpf_t, const mpf_t, unsigned long int);
- int
- main(int argc, char * argv[])
- {
- double var;
- unsigned long int eff;
- var = atof(argv[1]);
- eff = atof(argv[2]);
- mpf_t x, result;
- mpf_init(result);
- mpf_init_set_d(x, var);
- normal_cdf(result, x, eff);
- char format[50];
- sprintf(format, "norma_cdf(%%f) = %%.%dFe\n", eff);
- gmp_printf(format, var, result);
- mpf_clear(result);
- mpf_clear(x);
- return 0;
- }
- void
- normal_cdf(mpf_t result,const mpf_t x, unsigned long int eff)
- {
- mpz_t n;
- mpf_t a, error;
- mpq_t q;
- mpz_init(n);
- mpf_init(a);
- mpq_init(q);
- mpf_init(error);
- mpf_set_prec(a, PREC);
- mpf_set_prec(result, PREC);
- mpf_set_prec(error, PREC);
-
- mpf_set_str(a, "0.3989422804014326779399460599343818684758586311649346576659258296706579258993018385012523339073069364", 10);
- // printf("error\n");
- // gmp_printf("a = %.100Ff\n", a);
- // gmp_printf("error = %40Ff\n", error);
- // gmp_printf("x =%20Ff \n", x);
- mpf_set_d(result, 0.5);
- // gmp_printf("result =%20Ff \n", result);
- mpf_mul(a, a, x);
- // gmp_printf("a = %.100Ff\n", a);
- mpf_t dist, temp;
- mpf_init(dist);
- mpf_init(temp);
- mpf_set_prec(dist, PREC);
- mpf_set_prec(temp, PREC);
- mpz_t num, den;
- mpz_init(num);
- mpz_init(den);
- mpf_set_d(error, 10);
- // gmp_printf("error =%20Ff \n", error);
- mpf_pow_ui(error, error, eff + 1);
- // gmp_printf("error =%20Ff \n", error);
- mpf_ui_div(error, 1, error);
- // gmp_printf("error =%20Ff \n", error);
- do
- {
- // gmp_printf("\nthe %Zd-th loop \n", n);
- mpf_add(result, result, a);
- // gmp_printf("result =%20Ff \n", result);
- mpz_add_ui(n, n, 1);
- mpz_mul_ui(num, n, 2);
- mpz_sub_ui(num, num, 1);
- // gmp_printf("num =%Zd \n", num);
- mpz_add_ui(den, num, 2);
- mpz_mul(den, den, n);
- mpz_mul_ui(den, den, 2);
- // gmp_printf("den =%Zd \n", den);
- mpq_set_num(q, num);
- mpq_set_den(q, den);
- mpf_set_q(temp, q);
- // gmp_printf("temp = %20Ff\n", temp);
- mpf_mul(temp, temp, x);
- mpf_mul(temp, temp, x);
- mpf_neg(temp, temp);
- mpf_mul(a, a, temp);
- // gmp_printf("a = %.20Ff\n", a);
- mpf_set(dist, a);
- // gmp_printf("dist =%20Ff \n", dist);
- mpf_div(dist, dist, result);
- mpf_abs(dist, dist);
- // gmp_printf("dist =%.70Ff \n", dist);
- }while(mpf_cmp(dist, error) > 0);
- // gmp_printf("phi_cdf(%f) = %.4Fe \n", var, result);
- mpf_clear(a);
- mpq_clear(q);
- mpf_clear(dist);
- mpf_clear(temp);
- mpf_clear(error);
- mpz_clear(n);
- mpz_clear(num);
- mpz_clear(den);
- }
复制代码
编译时需要libgmp3-dev库,使用gcc -lgmp -o normal_cdf normal_cdf.c编译。
运行方法:normal_cdf var prec
第一个参数:要求概率函数的自变量。
第二个参数:结果的精确度,即小数点后面的位数。
这个级数的收敛速度不错,是你自己推导出来的吗?
佩服ing |
|