| 
 | 
 
 
发表于 2020-12-7 14:44:37
|
显示全部楼层
   本楼为最佳答案    
 
 
 本帖最后由 xieglt 于 2020-12-7 14:53 编辑  
 
后面才看到要考虑符号。又改了下,一个有符号的版本 
 
- #include <stdio.h>
 
 - #include <stdlib.h>
 
 - #include <string.h>
 
  
- #define BASE                (10000)
 
 - #define        NUM_LEN                (4)
 
 - #define        _BASE_SIZE        (1024)
 
 - #define ISINIT(p)        ((p->_data != 0) && (p->_flag == 0))
 
  
- typedef struct tagInteger
 
 - {
 
 -         int * _data;
 
 -         int _size;
 
 -         int _len;
 
 -         int _signed;
 
 -         int _flag;
 
 - }INTEGER,*LPINTEGER;
 
  
- int _InitInteger(LPINTEGER n,int size = 0)
 
 - {
 
 -         size = ((size == 0) ? _BASE_SIZE : size);
 
 -         
 
 -         n->_size = 0;
 
 -         n->_data = (int *)malloc(size * sizeof(int));
 
 -         
 
 -         if(n->_data == 0)
 
 -         {
 
 -                 return 0;
 
 -         }
 
  
-         memset(n->_data,0,size * sizeof(int));
 
 -         n->_len = 0;
 
 -         n->_size = size;
 
 -         n->_flag = 0;
 
 -         return 1;
 
 - }
 
  
- void _UninitInteger(LPINTEGER n)
 
 - {
 
 -         if(ISINIT(n))
 
 -         {
 
 -                 free(n->_data);
 
 -         }
 
 - }
 
  
- int _ResizeInteger(LPINTEGER n,int _size = 0)
 
 - {
 
 -         int len = n->_size;
 
 -         
 
 -         if(!ISINIT(n))
 
 -         {
 
 -                 return _InitInteger(n,_size);
 
 -         }
 
 -                 
 
 -         if(_size < _BASE_SIZE)
 
 -         {
 
 -                 n->_size += _BASE_SIZE;
 
 -         }
 
 -         else
 
 -         {
 
 -                 n->_size += _size;
 
 -         }
 
 -                 
 
 -         n->_data = (int *)realloc(n->_data,n->_size * sizeof(int));
 
 -                 
 
 -         if(n->_data == 0)
 
 -         {
 
 -                         return 0;
 
 -         }
 
 -         
 
 -         memset(n->_data + len,0,(n->_size - len) * sizeof(int));
 
 -         return 1;
 
 - }
 
  
- int _String2Integer(LPINTEGER pNum,char * number)
 
 - {
 
 -         int i = 0;
 
 -         int nRet = 0;
 
 -         char cByte = 0;
 
 -         int value = 0;
 
 -         int power = 0;
 
 -         int index =0;
 
 -         int len = strlen(number);
 
 -         int size = len / NUM_LEN + (len % NUM_LEN == 0 ? 0 : 1);
 
 -         int flag = 0;
 
  
-         do 
 
 -         {
 
 -                 if(len == 0)
 
 -                 {
 
 -                         break;
 
 -                 }
 
  
-                 
 
 -                 if(number[0]=='-' || number[0]=='+')
 
 -                 {
 
 -                         if(number[0] == '-')
 
 -                         {
 
 -                                 flag = 1;
 
 -                         }
 
 -                         
 
 -                         number ++;
 
 -                         len --;
 
 -                 }
 
 -                 
 
 -                 if(!ISINIT(pNum) && _InitInteger(pNum,size) == 0)
 
 -                 {
 
 -                         break;
 
 -                 }
 
  
-                 if(size > pNum->_size && _ResizeInteger(pNum,size) == 0)
 
 -                 {
 
 -                         break;
 
 -                 }
 
 -                 
 
 -                 for(i=0 ; i<len ; i++)
 
 -                 {
 
 -                         if(number[i]<'0' || number[i]>'9')
 
 -                         {
 
 -                                 break;
 
 -                         }
 
 -                 }
 
 -                 if(i < len--)
 
 -                 {
 
 -                         break;
 
 -                 }
 
  
 
-                 for(i=len ; i>=0 ; i--)
 
 -                 {
 
 -                         if((len - i) % NUM_LEN == 0)
 
 -                         {
 
 -                                 if(len - i != 0)
 
 -                                 {
 
 -                                         pNum->_data[index++] = value;
 
 -                                 }
 
  
-                                 value = 0;
 
 -                                 power = 1;
 
 -                         }
 
 -                         cByte = number[i] - 0x30;
 
 -                         value += power * cByte;
 
 -                         power *= 10;
 
 -                 }
 
  
-                 if(value != 0)
 
 -                 {
 
 -                         pNum->_data[index++] = value;
 
 -                 }
 
 -                 pNum->_signed = flag;
 
 -                 pNum->_len = index;
 
 -                 while(pNum->_data[pNum->_len-1] == 0)
 
 -                 {
 
 -                         pNum->_len--;
 
 -                 }
 
 -                 nRet = 1;
 
 -         }while(0);
 
  
-         return nRet;
 
 - }
 
  
- int _Integer2String(LPINTEGER pNum,char * number)
 
 - {
 
 -         int i = 0;
 
 -         int nRet = 0;
 
 -         char buffer[16] = {0};
 
 -         
 
 -         do 
 
 -         {
 
 -                 if(!ISINIT(pNum))
 
 -                 {
 
 -                         break;
 
 -                 }
 
  
-                 if(number == 0)
 
 -                 {
 
 -                         nRet = pNum->_len * (NUM_LEN + 1) + 1;
 
 -                         break;
 
 -                 }
 
  
-                 number[0] = 0;
 
  
-                 if(pNum->_signed != 0)
 
 -                 {
 
 -                         strcat(number,"-");
 
 -                 }
 
 -                 
 
 -                 for(i=pNum->_len-1 ; i>=0 ; i--)
 
 -                 {
 
 -                         if(i == pNum->_len-1)
 
 -                         {
 
 -                                 sprintf(buffer,"%d",pNum->_data[i]);
 
 -                         }
 
 -                         else
 
 -                         {
 
 -                                 sprintf(buffer,"%04d",pNum->_data[i]);
 
 -                         }
 
 -                         strcat(number,buffer);
 
 -                         if(i != 0)
 
 -                         {
 
 -                                 strcat(number,",");
 
 -                         }
 
 -                 }
 
  
-                 nRet = strlen(number);
 
 -         }while(0);
 
  
-         return nRet;
 
 - }
 
  
- void _PushBack(LPINTEGER src,int data)
 
 - {
 
  
-         if(src->_len == src->_size)
 
 -         {
 
 -                 if(!_ResizeInteger(src))
 
 -                 {
 
 -                         return;
 
 -                 }
 
 -         }
 
  
-         src->_data[src->_len++] = data;
 
 - }
 
  
- void _SimpleAdd(LPINTEGER src,LPINTEGER dst)
 
 - {
 
 -         int sizeofme = src->_len;
 
 -         int sizeofyou = dst->_len;
 
 -         int len = sizeofme >= sizeofyou ? sizeofme : sizeofyou;
 
 -         int i = 0;
 
 -         int value = 0;
 
 -         int carry = 0;
 
  
-         for(i=0 ; i<len ; i++)
 
 -         {
 
 -                 value = carry;
 
 -                 if(i < sizeofme)
 
 -                 {
 
 -                         value += src->_data[i];
 
 -                 }
 
  
-                 if(i < sizeofyou)
 
 -                 {
 
 -                         value += dst->_data[i];
 
 -                 }
 
  
-                 carry = value / BASE;
 
 -                 value %= BASE;
 
  
-                 if(i < sizeofme)
 
 -                 {
 
 -                         src->_data[i] = value;
 
 -                 }
 
 -                 else
 
 -                 {
 
 -                         _PushBack(src,value);
 
 -                 }
 
 -         }
 
  
-         if(carry != 0)
 
 -         {
 
 -                 if(i < sizeofme)
 
 -                 {
 
 -                         src->_data[i] = carry;
 
 -                 }
 
 -                 else
 
 -                 {
 
 -                         _PushBack(src,carry);
 
 -                 }
 
 -         }
 
 - };
 
  
- void _SimpleSub(LPINTEGER src,LPINTEGER dst)
 
 - {
 
 -         int sizeofme = src->_len;
 
 -         int sizeofyou = dst->_len;
 
 -         int i = 0;
 
 -         int value = 0;
 
 -         int carry = 0;
 
 -         
 
 -         for(i=0 ; i<sizeofme ; i++)
 
 -         {
 
 -                 value = src->_data[i];
 
  
-                 if(i < sizeofyou)
 
 -                 {
 
 -                         value -= dst->_data[i];
 
 -                 }
 
 -                 
 
 -                 value -= carry;
 
 -                 
 
 -                 if(value < 0)
 
 -                 {
 
 -                         value += BASE;
 
 -                         carry = 1;
 
 -                 }
 
 -                 else
 
 -                 {
 
 -                         carry = 0;
 
 -                 }
 
 -                 src->_data[i] = value;
 
 -         }
 
  
-         while(src->_data[src->_len-1] == 0)
 
 -         {
 
 -                 src->_len--;
 
 -         }
 
 - }
 
  
- int _UnsignedCompare(LPINTEGER src,LPINTEGER dst)
 
 - {
 
 -         int i = 0;
 
  
-         if(src->_len > dst->_len)
 
 -         {
 
 -                 return 1;
 
 -         }
 
 -         else if(src->_len < dst->_len)
 
 -         {
 
 -                 return -1;
 
 -         }
 
 -         
 
 -         for(i=src->_len-1 ; i>=0 ; i--)
 
 -         {
 
 -                 if(src->_data[i] > dst->_data[i])
 
 -                 {
 
 -                         return 1;
 
 -                 }
 
 -                 else if(src->_data[i] < dst->_data[i])
 
 -                 {
 
 -                         return -1;
 
 -                 }
 
 -         }
 
  
-         return 0;
 
 - }
 
  
- void _CopyInteger(LPINTEGER dst,LPINTEGER src)
 
 - {
 
 -         if(!ISINIT(dst))
 
 -         {
 
 -                 if(!_InitInteger(dst,src->_size))
 
 -                 {
 
 -                         return;
 
 -                 }
 
 -         }
 
 -         else if(dst->_size < src->_size)
 
 -         {
 
 -                 if(!_ResizeInteger(dst,src->_size))
 
 -                 {
 
 -                         return;
 
 -                 }
 
 -         }
 
  
-         memcpy(dst->_data,src->_data,src->_size);
 
 -         dst->_len = src->_len;
 
 -         dst->_signed = src->_signed;
 
 - }
 
  
- void _UnsignedSub(LPINTEGER src,LPINTEGER dst)
 
 - {
 
 -         INTEGER n;
 
 -         int _signed = src->_signed;
 
  
-         if(_UnsignedCompare(src,dst) == -1)
 
 -         {
 
  
-                 _CopyInteger(&n,dst);
 
 -                 _SimpleSub(&n,src);
 
 -                 _CopyInteger(src,&n);
 
 -                 _UninitInteger(&n);
 
 -                 src->_signed = !_signed;
 
 -         }
 
 -         else
 
 -         {
 
 -                 _SimpleSub(src,dst);
 
 -         }
 
 - }
 
  
- void _AddInteger(LPINTEGER src,LPINTEGER dst)
 
 - {
 
 -         int _signed = src->_signed - dst->_signed;
 
 -         if(_signed == 0)
 
 -         {
 
 -                 _SimpleAdd(src,dst);
 
 -         }
 
 -         else
 
 -         {
 
 -                 _UnsignedSub(src,dst);
 
 -         }
 
 - }
 
  
- void _SubInteger(LPINTEGER src,LPINTEGER dst)
 
 - {
 
 -         int _signed = src->_signed - dst->_signed;
 
 -         if(_signed != 0)
 
 -         {
 
 -                 _SimpleAdd(src,dst);
 
 -         }
 
 -         else
 
 -         {
 
 -                 _UnsignedSub(src,dst);
 
 -         }
 
 - }
 
  
- int main(int argc, char* argv[])
 
 - {
 
 -         INTEGER n,m;
 
 -         char buffer[128];
 
 -         _InitInteger(&n);
 
 -         _InitInteger(&m);
 
 -         _String2Integer(&n,"-1234567890987654321012345678909876543210123");
 
 -         _String2Integer(&m,"99998888777776666655555444433332222111100001234567890");
 
 -         
 
 -         _AddInteger(&n,&m);
 
 -         _Integer2String(&n,buffer);
 
 -         _UninitInteger(&n);
 
 -         _UninitInteger(&m);
 
 -         printf("%s",buffer);
 
 -         return 0;
 
 - }
 
  
  复制代码 |   
 
 
 
 |