其中有一些垃圾代码没有去除,也没有对代码进行优化,只是为了一个计算的需要而设计的
/***********************************************************
*author:hoboo
*email:hoboo@sohu.com
*功能:用于模拟计算大数据阶乘,返回详细的结果.
*程序中是计算2000!,返回的结果有5736位.程序最大
*可以计算返回结果位数为MAXLEN=10000位,每个乘数的
*最大位数为MAXSNGLLEN=20.
*时间:2007-12-19
*说明:本程序可以修改并用于研究目的,但请保存以上
*信息.如有Bug或改进,请以email通知本人.
*/
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <assert.h>
#define Combin(x,y) ((x)##(y))
#ifndef NULL
#define NULL 0
#endif
const int MAXLEN=10000;
const int MAXSNGLLEN=20;
int chartoint(char p)
{
int i;
int nRet=0;
char chrInd[10]={'0','1','2','3','4','5','6','7','8','9'};
for (i=0; i<10; i++)
{
if (p==chrInd[i])
{
nRet=i;
break;
}
}
return nRet;
}
int getstrlen(const char *pchr)
{
int i=0;
int nLen=0;
while (pchr[i]!='/0')
{
nLen++;
i++;
}
return nLen;
}
class LargeMathOp
{
friend LargeMathOp operator + (LargeMathOp&,LargeMathOp&);
friend LargeMathOp operator << (LargeMathOp&,int);
friend LargeMathOp operator * (LargeMathOp&,LargeMathOp&);
//friend LargeMathOp operator ++ ();
private:
int m_len;
public:
int m_math[MAXLEN];
public:
LargeMathOp(void);
LargeMathOp(int *nMath,int nLen);
int GetLength(){return m_len;}
int CalLength();
void SetLength(int nLength){m_len=nLength;}
int* GetValue(){return m_math;}
int GetValue(int nIndex){return m_math[nIndex];}
void SetValue(int nVal,int nIndex);
void SetValue(int nVal);
void PrintVal(int count);
LargeMathOp& operator = (LargeMathOp& op1);
~LargeMathOp();
};
inline LargeMathOp::~LargeMathOp ()
{
}
LargeMathOp::LargeMathOp()
{
int i=0;
m_len=0;
for (i=0 ;i < MAXLEN ; i++)
{
m_math[i]=0;
}
}
LargeMathOp::LargeMathOp(int *nMath,int nLen)
{
int i=0;
m_len=nLen;
for (i=0; i<nLen; i++)
{
m_math[i]=nMath[i];
/*
#ifdef MATHOP_DEBUG
printf("Overflow during setvalue");
throw();
#endif
*/
}
for (i=nLen; i<MAXLEN; i++)
{
m_math[i]=0;
}
CalLength();
}
void LargeMathOp::SetValue(int nVal,int nIndex)
{
m_math[nIndex]=nVal;
if (nIndex>=m_len) //--
{
m_len=nIndex+1;
}
//CalLength();
}
int LargeMathOp::CalLength()
{
int i=0;
int nLen=0;
for (i=MAXLEN - 1; i>=0; i--)
{
if ((m_math[i]<0) || (m_math[i]>9))
{
m_math[i]=0;
}
if (m_math[i]>0)
{
nLen=i+1;
m_len=nLen;
break;
}
}
return nLen;
}
void LargeMathOp::SetValue(int nVal)
{
int nLength=0;
char pVal[MAXSNGLLEN];
int i=0;
itoa(nVal,pVal,10);
nLength=getstrlen(pVal);
for (i=0; i<nLength; i++)
{
m_math[nLength - 1 - i]=chartoint(pVal[i]);
}
m_len=nLength;
}
void LargeMathOp::PrintVal(int count)
{
int i=0;
int j=0;
int nRow=1;
const int MAXCOL=6;
printf("%d ",nRow);
for (i=m_len-1; i>=0; i--,j++)
{
if (j > (count - 1))
{
nRow++;
printf("/n%d",nRow);
int k=0;
char p[MAXCOL];
for (k=0; k<(6 - getstrlen(itoa(nRow,p,10))); k++)
{
printf(" ");
}
j=0;
}
printf("%d",m_math[i]);
}
}
LargeMathOp operator + (LargeMathOp &op1,LargeMathOp &op2)
{
LargeMathOp retResult;
int i=0;
int nUpBit=0;
int ntemp=0;
int nLength=(op1.GetLength()>op2.GetLength()?op1.GetLength():op2.GetLength());
for (i=0; i<nLength; i++)
{
ntemp=op1.m_math[i]+op2.m_math[i]+nUpBit;
if (ntemp>9)
{
nUpBit=1;
ntemp-=10;
}
else
{
nUpBit=0;
}
retResult.m_math[i]=ntemp;
/*
if (retResult.m_math[(op1.m_len>op2.m_len?op1.m_len:op2.m_len)+1]!=0)
{
retResult.m_len=(op1.m_len>op2.m_len?op1.m_len:op2.m_len)+1;
}
else
{
retResult.m_len=(op1.m_len>op2.m_len?op1.m_len:op2.m_len);
}
*/
}
retResult.SetLength (nLength);
if (nUpBit>0)
{
retResult.m_math[i]=nUpBit;
retResult.SetLength(i + 1);
}
//retResult.CalLength();
return retResult;
}
LargeMathOp& LargeMathOp::operator = (LargeMathOp &op1)
{
m_len=op1.GetLength ();
int i=0;
for (i = 0; i < m_len; i++)
{
m_math[i]=op1.GetValue (i);
}
return (*this);
}
LargeMathOp operator << (LargeMathOp &op1,int nBit)
{
int i=0;
int nLength=op1.GetLength();
//assert((nLength+nBit)<MAXLEN);
for (i=0; i<nLength; i++)
{
op1.SetValue(op1.GetValue(nLength-1-i),nLength-1-i+nBit);
}
for (i=0; i<nBit; i++)
{
op1.SetValue(0,i);
}
//op1.CalLength();
return op1;
}
/*
LargeMathOp operator ++()
{
LargeMathOp op2;
op2.SetValue(1,0);
(*this)=(*this)+op2;
return *this;
}
*/
/*------通过叠加实现乘法运算-------*/
LargeMathOp operator *(LargeMathOp &op1,LargeMathOp &op2)
{
LargeMathOp retOp;
LargeMathOp mo_temp;
int i=0;
int j=0;
int nLength=op2.CalLength();
for (i=0; i<nLength; i++)
{
mo_temp=(op1 << i);
for (j=0; j<op2.GetValue(i); j++)
{
retOp=retOp+mo_temp;
}
}
retOp.CalLength();
return retOp;
}
int main()
{
/*----test data
int ls[15]={1,2,3,4,5,6,7,8,9,0,3,9,7,8,6};
int is[]={7,8,9,0,3,9,7,8,6};
LargeMathOp aa1(ls,15);
LargeMathOp aa2(is,9);
*/
LargeMathOp aa1;
LargeMathOp aa2;
//clrscr();
/*----------test function */
/*
printf("/n");
aa1.PrintVal();
aa1=(aa1<<4);
printf("/n");
aa1.PrintVal();
printf("/n");
aa2.PrintVal();
printf("/n");
aa2=(aa2<<5);
aa2.PrintVal();
printf("/n");
aa1=aa1+aa2;
aa1.PrintVal();
*/
int i=0;
int nLength=0;
aa1.SetValue(1);
//printf("/n----------------------aa1-------------------------/n");
//aa1.PrintVal();
for (i=2; i<3001;i++)
{
printf("/n---------------%d!---------------------------/n",i);
aa2.SetValue(i);
aa2.PrintVal(60);
printf("/n");
aa1=aa1*aa2;
nLength=aa1.GetLength();
printf(" %d bits /n",nLength);
aa1.PrintVal(60);
//printf("/n");
}
printf("/n-------------%d!------------------------------/n",i);
aa2.PrintVal(60);
printf("/n-------------Result----------------------------/n");
nLength=aa1.GetLength();
printf(" %d bits /n",nLength);
aa1.PrintVal(60);
return 0;
}