两个大的正整数相加之和(C语言实现)

typedef unsigned char BYTE;

// BCD 码串字节序反转
void ReverseNum(BYTE* num, int cnt);

/*
两个大的正整数相加之和, 其中:
参数:
   num1     整数的BCD码串1
   size1    BCD码串1的字节数
   num2     整数的BCD码串2
   size2    BCD码串2的字节数
   dest     存放结果BCD码串的缓冲区
   size     传入 dest 缓冲区的尺寸
返回值:
   -3       相加失败, 参数不合法
   -2       相加失败, BCD码串2存在不合法字符
   -1       相加失败, BCD码串1存在不合法字符
    0       相加失败, 结果BCD码串的缓冲区尺寸太小
   >0       相加成功, 返回BCD码串的字节数
*/
int AddBCDInt(const void* num1, int size1, const void* num2, int size2,
                    void* dest, int size)
{
   int result  = -3;
   int nCnt    = 0;  // 返回字节数
   BYTE btNum1 = 0, btNum2 = 0, btDestNum = 0;
   BYTE btHighNum1  = 0, btLowNum1 = 0; 
   BYTE btHighNum2  = 0, btLowNum2 = 0; 
   BYTE btHighNum   = 0, btLowNum  = 0; 
   BYTE num1Size    = 0, num2Size  = 0;   // 截掉首字节为0后num1,num2的真实size
   int maxSize      = 0;
   BYTE carryFlag   = 0; // 进位标记

   // 参数合法性判定
   if ( num1!=NULL && size1>0 && num2!=NULL && size2>0 && dest!=NULL && size>0 )
   {
      num1Size = size1;
      num2Size = size2;
      //  截掉num1\num2为0首字节
      for ( int i=0; i<size1; i++ )
      {
         if (  ((BYTE *)num1)[i] == 0  )  num1Size --;
         else  break;
      }

      for ( int i=0; i<size2; i++ )
      {
         if (  ((BYTE *)num2)[i] == 0  )  num2Size --;
         else  break;
      }

      maxSize = (num1Size>num2Size) ? (num1Size+1) : (num2Size+1); // 相加结果最大字节数maxSize
      while( maxSize-- > 0 )
      {
         // num1
         if ( size1 > 0 )
         {
            btNum1 = ( (BYTE *)num1 )[--size1];
            btLowNum1  = btNum1 & 0x0F;
            btHighNum1 = btNum1 >> 4;

            // btNum1高低位合法性验证
            if ( btLowNum1>9 || btHighNum1>9 )
            {
               result = -1;  // 相加失败, BCD码串1存在不合法字符
               break;
            }
         }
         else
         {
            btNum1 = 0;
            btLowNum1  = 0;
            btHighNum1 = 0;
         }
         // num2
         if ( size2 > 0 )
         {
            btNum2 = ( (BYTE *)num2 )[--size2];
            btLowNum2  = btNum2 & 0x0F;
            btHighNum2 = btNum2 >> 4;

            // btNum2高低位合法性验证
            if ( btLowNum2>9 || btHighNum2>9 )
            {
               result = -2;  // 相加失败, BCD码串2存在不合法字符
               break;
            }
         }
         else
         {
            btNum2 = 0;
            btLowNum2  = 0;
            btHighNum2 = 0;

         }
         // 字符合法
         btLowNum  = btLowNum1  + btLowNum2;
         btHighNum = btHighNum1 + btHighNum2;
         
         btLowNum += carryFlag;  // 进位
         if ( btLowNum>9 )            // 进位加6修正
         {
            btLowNum -= 10;
            btHighNum++;
         }

         // 低位修正结果使高位大于9时,高位进行加6修正
         if ( btHighNum > 9 )
         {
            btHighNum += 6;
            carryFlag = 1;
         }
         else
            carryFlag = 0;
			
         btDestNum = (btHighNum << 4) + btLowNum;
         if ( btDestNum != 0 || maxSize > 0 )
         {
            if ( size > nCnt )
            {
               ( (BYTE *)dest )[nCnt++] = btDestNum;
               result = nCnt;
            }
            else
            {
               result = 0;  // 相加失败, 结果BCD码串的缓冲区尺寸太小
               break;
            }  
         }
      }

      // BCD 码串按十进制数的从高到低存放
      if ( result > 0 )
      {
         ReverseNum((BYTE *)dest , nCnt);
      }
   }
   return result;
}

/*
两个大的正整数相加之和, 其中:
参数:
   num      整数的BCD码串
   cnt      BCD码串的字节数
返回值:
   无
*/
void ReverseNum(BYTE* num, int cnt)
{
   BYTE tmp;
   for ( int i = 0; i < (cnt/2); i++ )
   {
      tmp = num[i];
      num[i] = num[cnt-1-i];
      num[cnt-1-i] = tmp;
   }
}

  

posted @ 2017-07-03 20:07  __kylong  阅读(2421)  评论(1编辑  收藏  举报