#include "stdafx.h" #include "math.h" #define MAX_N 10000000.00 //能够计算的最大的n值,如果你想计算更大的数对数,可将其改为更大的值 #define MAX_MANTISSA (1e308/MAX_N) //最大尾数 struct bigNum { double n1; //表示尾数部分 int n2; //表示指数部分 }; void calcFac(struct bigNum *p,int n) { int i; double MAX_POW10_LOG=(floor(log10(1e308/MAX_N))); //最大尾数的常用对数的整数部分, double MAX_POW10= (pow(10.00, MAX_POW10_LOG)); // 10 ^ MAX_POW10_LOG p->n1=1; p->n2=0; for (i=1;i<=n;i++) { if (p->n1>=MAX_MANTISSA) { p->n1 /= MAX_POW10; p->n2 += MAX_POW10_LOG; } p->n1 *=(double)i; } } void printfResult(struct bigNum *p,char buff[]) { while (p->n1 >=10.00 ) {p->n1/=10.00; p->n2++;} sprintf(buff,"%.14fe%d",p->n1,p->n2); } int main(int argc, char* argv[]) { struct bigNum r; char buff[32]; int n; printf("n=?"); scanf("%d",&n); calcFac(&r,n); //计算n的阶乘 printfResult(&r,buff); //将结果转化一个字符串 printf("%d!=%s/n",n,buff); return 0; }
#include "stdafx.h" #include "math.h" #define MAX_N 10000000.00 //能够计算的最大的n值,如果你想计算更大的数对数,可将其改为更大的值 #define MAX_MANTISSA (1e308/MAX_N) //最大尾数 typedef unsigned short WORD; struct bigNum { double n1; //表示尾数部分 int n2; //表示阶码部分 }; short GetExpBase2(double a) // 获得 a 的阶码 { // 按照IEEE 754浮点数格式,取得阶码,仅仅适用于Intel 系列 cpu WORD *pWord=(WORD *)(&a)+3; WORD rank = ( (*pWord & 0x7fff) >>4 ); return (short)(rank-0x3ff); } double GetMantissa(double a) // 获得 a 的 尾数 { // 按照IEEE 754浮点数格式,取得尾数,仅仅适用于Intel 系列 cpu WORD *pWord=(WORD *)(&a)+3; *pWord &= 0x800f; //清除阶码 *pWord |= 0x3ff0; //重置阶码 return a; } void calcFac(struct bigNum *p,int n) { int i; p->n1=1; p->n2=0; for (i=1;i<=n;i++) { if (p->n1>=MAX_MANTISSA) //继续相乘可能溢出,调整之 { p->n2 += GetExpBase2(p->n1); p->n1 = GetMantissa(p->n1); } p->n1 *=(double)i; } } void printfResult(struct bigNum *p,char buff[]) { double logx=log10(p->n1)+ p->n2 * log10(2);//求计算结果的常用对数 int logxN=(int)(floor(logx)); //logx的整数部分 sprintf(buff,"%.14fe%d",pow(10,logx-logxN),logxN);//转化为科学计算法形式的字符串 } int main(int argc, char* argv[]) { struct bigNum r; char buff[32]; int n; printf("n=?"); scanf("%d",&n); calcFac(&r,n); //计算n的阶乘 printfResult(&r,buff); //将结果转化一个字符串 printf("%d!=%s/n",n,buff); return 0; }
inline short GetExpBase2(double a) // 获得 a 的阶码 { // 按照IEEE 754浮点数格式,取得阶码,仅仅适用于Intel 系列 cpu WORD *pWord=(WORD *)(&a)+3; WORD rank = ( (*pWord & 0x7fff) >>4 ); return (short)(rank-0x3ff); } inline double GetMantissa(double a) // 获得 a 的 尾数 { // 按照IEEE 754浮点数格式,取得尾数,仅仅适用于Intel 系列 cpu WORD *pWord=(WORD *)(&a)+3; *pWord &= 0x800f; //清除阶码 *pWord |= 0x3ff0; //重置阶码 return a; } void calcFac(struct bigNum *p,int n) { int i,t; double f,max_mantissa; p->n1=1;p->n2=0;t=n-32; for (i=1;i<=t;i+=32) { p->n2 += GetExpBase2(p->n1); p->n1 = GetMantissa(p->n1); f=(double)i; p->n1 *=(double)(f+0.0); p->n1 *=(double)(f+1.0); p->n1 *=(double)(f+2.0); p->n1 *=(double)(f+3.0); p->n1 *=(double)(f+4.0); p->n1 *=(double)(f+5.0); p->n1 *=(double)(f+6.0); p->n1 *=(double)(f+7.0); p->n1 *=(double)(f+8.0); p->n1 *=(double)(f+9.0); p->n1 *=(double)(f+10.0); p->n1 *=(double)(f+11.0); p->n1 *=(double)(f+12.0); p->n1 *=(double)(f+13.0); p->n1 *=(double)(f+14.0); p->n1 *=(double)(f+15.0); p->n1 *=(double)(f+16.0); p->n1 *=(double)(f+17.0); p->n1 *=(double)(f+18.0); p->n1 *=(double)(f+19.0); p->n1 *=(double)(f+20.0); p->n1 *=(double)(f+21.0); p->n1 *=(double)(f+22.0); p->n1 *=(double)(f+23.0); p->n1 *=(double)(f+24.0); p->n1 *=(double)(f+25.0); p->n1 *=(double)(f+26.0); p->n1 *=(double)(f+27.0); p->n1 *=(double)(f+28.0); p->n1 *=(double)(f+29.0); p->n1 *=(double)(f+30.0); p->n1 *=(double)(f+31.0); } for (;i<=n;i++) { p->n2 += GetExpBase2(p->n1); p->n1 = GetMantissa(p->n1); p->n1 *=(double)(i); } }
注1:10^0,表示10的0次方
[email protected] ,版权所有,转载请注明出处。