大数相乘

#include <stdlib.h>

/* 输出数的最大位数 */
#define MAX_LEN 200

/* 链表节点 */
typedef struct BIGINT_NODE
{
 struct BIGINT_NODE *pPre;
 struct BIGINT_NODE *pNext;
 unsigned short usData;
}BIGINT_NODE_STRU;

/* 双向链表 */
typedef struct BIGINT
{
 BIGINT_NODE_STRU *pHead;
}BIGINT_STRU;

/* 链表加入节点方式 */
typedef enum INSERT_METHOD
{
    PRE,
    NEXT
}INSERT_METHOD_ENUM;


int Init(BIGINT_STRU *pBigInt);

int Insert(INSERT_METHOD_ENUM eMothed, BIGINT_STRU *pBigInt, unsigned short usData);

int Multiply(BIGINT_STRU *pBigInt, unsigned short usMultiplier);
void DeleteZeroNode(BIGINT_STRU *pBigInt);

int Div(const BIGINT_STRU *pDividend,
  const unsigned short usDividor,
  BIGINT_STRU *pQuotient,
  unsigned short *usRemainder
);

void Destroy(BIGINT_STRU *pBigInt);

void ToString(const BIGINT_STRU *pBigInt, char *pOut, unsigned int unLen);

void Reverse(char *pOut,  unsigned int unLen);

int main(int argc, char *argv[])
{
 BIGINT_STRU stBigInt;
 unsigned short suIndex;
 unsigned short suTestNum = 13;
 char *buff = NULL;
 if ( 0 != Init(&stBigInt) )
 {
  return 1;
 }
 
 for ( suIndex = 1 ; suIndex <= suTestNum; suIndex++ )
 {
   Multiply(&stBigInt, suIndex);
 }
 buff = (char *)malloc((MAX_LEN + 1) * sizeof(char));
 if(NULL == buff)
 {
  return 1;
 }
 ToString(&stBigInt, buff, MAX_LEN);
 printf("%s\n", buff);

 free(buff);
 Destroy(&stBigInt);
    return 0;
}

int Init(BIGINT_STRU *pBigInt)
{
 BIGINT_NODE_STRU *pNode = NULL;
 if ( NULL == pBigInt )
 {
  return 1;
 }

 pNode = (BIGINT_NODE_STRU *)malloc(sizeof(BIGINT_NODE_STRU));
 if ( NULL == pNode)
 {
  return 1;
 }

 pNode->usData = 0;
 pNode->pNext = pNode;
 pNode->pPre = pNode;
 pBigInt->pHead = pNode;

 return 0;
}

int Insert(INSERT_METHOD_ENUM eMothed, BIGINT_STRU *pBigInt, unsigned short usData)
{
 BIGINT_NODE_STRU *pNode = NULL;
 if ( NULL == pBigInt )
 {
  return 1;
 }

 pNode = (BIGINT_NODE_STRU *)malloc(sizeof(BIGINT_NODE_STRU));
 if ( NULL == pNode)
 {
  return 1;
 }

 pNode->usData = usData;
 if ( NEXT == eMothed)
 {
  pNode->pNext = pBigInt->pHead->pNext;
  pNode->pPre = pBigInt->pHead;
  pBigInt->pHead->pNext->pPre= pNode;
  pBigInt->pHead->pNext = pNode;
 }
 else if ( PRE == eMothed)
 {
  pNode->pNext = pBigInt->pHead;
  pNode->pPre = pBigInt->pHead->pPre;
  pBigInt->pHead->pPre->pNext= pNode;
  pBigInt->pHead->pPre = pNode;
 }

 return 0;
}

int Multiply(BIGINT_STRU *pBigInt, unsigned short usMultiplier)
{
 BIGINT_NODE_STRU *pPos = NULL;
 unsigned int unResult = 0;
 unsigned short usLow = 0;
 unsigned short usHigh = 0;

 if(NULL == pBigInt)
 {
  return 1;
 }

 if(pBigInt->pHead->pPre == pBigInt->pHead)
 {
  Insert(NEXT, pBigInt, usMultiplier);
  return 0;
 }

 pPos = pBigInt->pHead->pPre;
 while(pPos != pBigInt->pHead)
 {
  unResult = pPos->usData * usMultiplier + usHigh;
  usLow = (unsigned short)(0x0000ffff & unResult) ;
  usHigh = (unsigned short)(0x0000ffff & (unResult >> 16));
  pPos->usData = usLow;

  pPos = pPos->pPre;
 }
 if(0 != Insert(NEXT, pBigInt, usHigh))
 {
  return 1;
 }
 DeleteZeroNode(pBigInt);
 return 0;
}

void DeleteZeroNode(BIGINT_STRU *pBigInt)
{
 BIGINT_NODE_STRU *pPos = NULL;
 BIGINT_NODE_STRU *pTmp = NULL;

 if(NULL == pBigInt)
 {
  return;
 }

 pPos = pBigInt->pHead->pNext;
 while(pBigInt->pHead != pPos && 0 == pPos->usData)
 {
  pTmp = pPos;
  pPos->pPre->pNext = pPos->pNext;
  pPos->pNext->pPre = pPos->pPre;
  pPos = pPos->pNext;
  free(pTmp);
 }
}

int Div(const BIGINT_STRU *pDividend,
  const unsigned short usDividor,
  BIGINT_STRU *pQuotient,
  unsigned short *usRemainder
)
{
 BIGINT_NODE_STRU *pPos = NULL;
 unsigned int unUnite = 0;
 unsigned short usQuotient = 0;
 unsigned short usRemainder2 = 0;

 if ( NULL == pDividend || NULL == pQuotient )
 {
     return 1;
 }
 if ( 0 == usDividor )
 {
     return 1;
 }

 pPos = pDividend->pHead->pNext;
 while ( pDividend->pHead != pPos)
 {
  unUnite = usRemainder2;
  unUnite = (unUnite << 16) + pPos->usData;
  usQuotient = unUnite / usDividor;
  usRemainder2 = unUnite % usDividor;
  if(0 != Insert(PRE, pQuotient, usQuotient))
  {
   return 1;
  }
     pPos = pPos->pNext;
 }
 *usRemainder = usRemainder2;
 DeleteZeroNode(pQuotient);
    return 0;
}

void Destroy(BIGINT_STRU *pBigInt)
{
 BIGINT_NODE_STRU *pPos = NULL;
 BIGINT_NODE_STRU *pTmp = NULL;

 if( NULL == pBigInt )
 {
  return;
 }

 pPos = pBigInt->pHead->pNext;
 while(pBigInt->pHead != pPos)
 {
  pTmp = pPos;
  pPos->pPre->pNext = pPos->pNext;
  pPos->pNext->pPre = pPos->pPre;
  pPos = pPos->pNext;
  free(pTmp);
 }
 free(pBigInt->pHead);
}

void ToString(const BIGINT_STRU *pBigInt, char *pOut, unsigned int unLen)
{
 unsigned short usRemainder = 0;
 unsigned int unCount = 0;
 BIGINT_STRU pQuotient;
 if ( 0 != Init(&pQuotient) )
 {
  return;
 }

 Div(pBigInt, 10, &pQuotient, &usRemainder);
 pOut[unCount++] = '0' + usRemainder;

 while(pQuotient.pHead != pQuotient.pHead->pNext)
 {
  BIGINT_STRU pQuotient2;
  if ( 0 != Init(&pQuotient2) )
  {
   return;
  }
  Div(&pQuotient, 10, &pQuotient2, &usRemainder);
  Destroy(&pQuotient);
  pQuotient.pHead = pQuotient2.pHead;
  if(unLen == unCount)
  {
   Destroy(&pQuotient);
   Reverse(pOut, unCount - 1);
   pOut[unCount] = '\0';
   return;
  }
  pOut[unCount++] = '0' + usRemainder;
 }
 Reverse(pOut, unCount - 1);
 pOut[unCount] = '\0';
 Destroy(&pQuotient);
}

void Reverse(char *pOut, unsigned int unLen)
{
 unsigned int unStart = 0;
 unsigned int unEnd = unLen;
 char cTmp;

 if(NULL == pOut)
 {
  return;
 }

 while(unStart < unEnd)
 {
  cTmp = pOut[unStart];
  pOut[unStart] = pOut[unEnd];
  pOut[unEnd] = cTmp;

  unStart++;
  unEnd--;
 }
}

你可能感兴趣的:(大数相乘)