WV.24-大数阶乘算法4-近似计算之二

近似计算之二

 

在《阶乘之计算从入门到精通-近似计算之一》中,我们采用两个数来表示中间结果,使得计算的范围扩大到1千万,并可0.02秒内完成10000000!的计算。在保证接近16位有效数字的前提下,有没有更快的算法呢。很幸运,有一个叫做Stirling的公式,它可以快速计算出一个较大的数的阶乘,而且数越大,精度越高。有http://mathworld.wolfram.com查找Stirling’s Series可找到2个利用斯特林公式求阶乘的公式,一个是普通形式,一个是对数形式。前一个公式包含一个无穷级数和的形式,包含级数前5项的公式为n!=sqrt(2*PI*n)*(n/e)n*(1+ 1/12/n+ 1/288/n2 –139/51840/n3-571/2488320/n4+…),这里的PI为圆周率,e为自然对数的底。后一个公式也为一个无穷级数和的形式,一般称这个级数为斯特林(Stirling)级数,包括级数前3项的n!的对数公式为:ln(n!)=0.5*ln(2*PI)+(n+0.5)*ln(n)-n+(1/12/n -1/360/n3 + 1/1260/n5)-…,下面我们分别用这两个公式计算n!.

完整的代码如下:

#include "stdafx.h"
#include "math.h"
#define PI       3.1415926535897932384626433832795
#define E 2.7182818284590452353602874713527
struct bigNum
{
       double n; //科学计数法表示的尾数部分
       int    e; //科学计数法表示的指数部分,若一个bigNum为x,这x=n * 10^e
};
const double a1[]=
{     1.00, 1.0/12.0, 1.0/288, -139/51840,-571.0/2488320.0 };
const double a2[]=
{     1.0/12.0, -1.0/360, 1.0/1260.0 };
void printfResult(struct bigNum *p,char buff[])
{
       while (p->n >=10.00 )
       {p->n/=10.00; p->e++;}
       sprintf(buff,"%.14fe%d",p->n,p->e);
}
// n!=sqrt(2*PI*n)*(n/e)^n*(1+ 1/12/n+ 1/288/n^2 -139/51840/n^3-571/2488320/n^4+…)
void calcFac1(struct bigNum *p,int n)
{
       double logx,
              s,            //级数的和
              item;  //级数的每一项   
       int i;
       // x^n= pow(10,n * log10(x));
       logx= n* log10((double)n/E);
       p->e= (int)(logx);   p->n= pow(10.0, logx-p->e);
       p->n *= sqrt( 2* PI* (double)n);
      
      //求(1+ 1/12/n+ 1/288/n^2 -139/51840/n^3-571/2488320/n^4+…)
       for (item=1.0,s=0.0,i=0;i<sizeof(a1)/sizeof(double);i++)
       {
              s+= item * a1[i];
              item /= (double)n; //item= 1/(n^i)
       }
       p->n *=s;
}
//ln(n!)=0.5*ln(2*PI)+(n+0.5)*ln(n)-n+(1/12/n -1/360/n^3 + 1/1260/n^5 -...)
void calcFac2(struct bigNum *p,int n)
{
       double logR;
       double s, //级数的和
       item;       //级数的每一项
       int i;
      
       logR=0.5*log(2.0*PI)+((double)n+0.5)*log(n)-(double)n;
      
       // s= (1/12/n -1/360/n^3 + 1/1260/n^5)
       for (item=1/(double)n,s=0.0,i=0;i<sizeof(a2)/sizeof(double);i++)
       {
              s+= item * a2[i];
              item /= (double)(n)* (double)n; //item= 1/(n^(2i+1))
       }
       logR+=s;
      
       //根据换底公式,log10(n)=ln(n)/ln(10)
       p->e = (int)( logR / log(10));
       p->n = pow(10.00, logR/log(10) - p->e);
}
int main(int argc, char* argv[])
{
       struct bigNum r;
       char buff[32];
       int n;
       printf("n=?");
       scanf("%d",&n);
      
       calcFac1(&r,n);            //用第一种方法,计算n的阶乘
       printfResult(&r,buff);    //将结果转化一个字符串
       printf("%d!=%s by method 1/n",n,buff);
       calcFac2(&r,n);            //用第二种方法,计算n的阶乘
       printfResult(&r,buff);    //将结果转化一个字符串
       printf("%d!=%s by method 2/n",n,buff);
       return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
包含章节:课后习题答案 第1章数字媒体技术概论 1.1媒体及其特性 1.1.1媒体概念 1.1.2媒体特性 1.2数字媒体及其特性 1.2.1数字媒体概念 1.2.2数字媒体特性 1.2.3数字媒体传播模式 1.3数字媒体技术的研究领域 1.3.1数字媒体内容产业 1.3.2数字媒体技术发展趋势 1.3.3数字媒体技术研究领域 1.3.4数字媒体应用领域 练习与思考 第2章数字音频技术基础 2.1音频技术及其特性 2.1.1音频的概念及特性 2.1.2模拟音频记录设备及特性. 2.1.3模拟音频处理设备 2.2音频数字化 2.2.1数字音频 2.2.2音频的数字化过程 2.3数字音频质量及格式 2.3.1音频数据率及质量 2.3.2声音文件格式 2.4数字音频的编辑技术 2.4.1数字音频的编辑方式 2.4.2数字音频设备 2.4.3数字音频编辑软件简介 2.4.4数字音频编辑实例 2.5数字音频技术应用 练习与思考 第3章数字图像的处理技术 3.1图像颜色模型 3.1.1视觉系统对颜色的感知 3.1.2RGB颜色模型 3.1.3CMYK颜色模型 3.1.4HSB颜色模型 3.1.5YUV与YIQ颜色模型 3.1.6CIELab颜色模型 3.2彩色空间的线性变换 3.2.1YUV与RGB彩色空间变换 3.2.2YIQ与RGB彩色空间变换 3.2.3HSI(HSB)与RGB之间的转换 3.2.4YCrCb与RGB彩色空间变换 3.3图像的基本属性及种类 3.3.1分辨率 3.3.2颜色深度 3.3.3真彩色、伪彩色与直接色 3.3.4图像的大小及种类 3.4数字图像的获取技术 3.4.1位图的获取设备与技术 3.4.2矢量图的获取设备与技术 3.5图像创意设计与编辑技术 3.5.1图像处理软件简介 …… 第4章数字视频及编辑 第5章数字动画技术 第6章游戏设计技术 第7章数字媒体的Web集成与应用 第8章数字媒体压缩技术 第9章数字媒体存储技术 第10章数字媒体管理与保护 第11章数字媒体的传输技术 第12章数字媒体技术发展趋势
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值