|
发表于 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;
- }
复制代码 |
|