2000!计算的详细结果

来源:互联网 发布:ipad无法更新软件 编辑:程序博客网 时间:2024/05/19 20:21

其中有一些垃圾代码没有去除,也没有对代码进行优化,只是为了一个计算的需要而设计的

 /***********************************************************

*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;
}
 

原创粉丝点击