大数相减

longDataMinus.c
#include <stdio.h> #include <string.h> #include <malloc.h> #include <assert.h> #define MAX_DATA_LEN 1000 #define TRUE 1 #define FALSE 0 #define OK 0 #define ERROR -1 typedef struct{ int intNum; int dotPos; }IntDotInfo; char* result = NULL; int findIntBitCount(char* str) { int i=0,len; len=strlen(str); for(i=0;i<=len-1;++i) { if((str[i])=='.') { return i; } } return i; } int findDotBitCount(char* str) { int len; len=(int)strlen(str); if(len ==findIntBitCount(str)) return 0; else return strlen(str)-findIntBitCount(str)-1; } int stringValueCompare(char *sub1,char* sub2) { int len_str1,len_str2; int IntNum1=0,IntNum2=0; len_str1=strlen(sub1); len_str2=strlen(sub2); IntNum1=findIntBitCount(sub1); IntNum2=findIntBitCount(sub2); if(IntNum1 < IntNum2) return 1; else if((IntNum1==IntNum2) && (sub1[0]<sub2[0])) return 1; return 0; } int isPositive(char* s) { if(s[0]=='-') return FALSE; else return TRUE; } int getIntDotInfo(char* sub1,char* sub2,IntDotInfo *data1,IntDotInfo *data2) { if(sub1==NULL || sub2 == NULL) return ERROR; data1->intNum=findIntBitCount(sub1); data1->dotPos=findDotBitCount(sub1); data2->intNum=findIntBitCount(sub2); data2->dotPos=findDotBitCount(sub2); return OK; } int alignNZero(int n, char *s) { int i; for(i=0;i<n;i++) s[i]='0'; s[i]=''; return OK; } int minusBitByBit(int *a,int *b, int *c, int bitLen,int borrow) { int i; for(i=0;i<=bitLen;i++) { c[i]=((a[i]-b[i]-borrow)>=0) ? (a[i]-b[i]-borrow):(a[i]-b[i]-borrow+10); borrow=((a[i]-b[i]-borrow)>=0) ? 0 : 1; } return borrow; } int plusBitByBit(int* s1,int* s2, int *sum, int Len, int carry) { int i; for(i=0;i<=Len-1;i++) { sum[i] = (s1[i] + s2[i] + carry) % 10; carry = (s1[i] + s2[i] + carry) / 10; } return carry; } int intBitToSring(int *data,char* dataOut, int HighBit) { int i,k; if(NULL == data) { return ERROR; } for(i=HighBit;i>=0;i--) { if(data[i]!=0)//||( c[i]==0 && c[i-1]+'0'=='.')) break; } for(i,k=0;i>=0;i--,k++) { dataOut[k]=data[i]+'0'; } dataOut[k]=''; return OK; } int stringToIntBit(char* data, int *dataOut) { int i=0,len_str1=0; len_str1=strlen(data); for(i=0;i<=len_str1-1;++i) { dataOut[i]=data[len_str1-1-i]-'0'; } return OK; } int bigDataMinus(char* sub1,char* sub2, char* sub) { int i,resultLenMax; int borrow=0; int intNum1=0,intNum2=0,dotNum1=0,dotNum2=0,shift=0; int a[1000]={0},b[1000]={0},c[1000]={0}; IntDotInfo data1={0}; IntDotInfo data2={0}; stringToIntBit(sub1, &a[0]); stringToIntBit(sub2, &b[0]); if(OK != getIntDotInfo(sub1,sub2,&data1,&data2)) { return ERROR; } intNum1=data1.intNum; dotNum1=data1.dotPos; intNum2=data2.intNum; dotNum2=data2.dotPos; resultLenMax=(intNum1>intNum2 ? intNum1 : intNum2) + (dotNum1>dotNum2 ? dotNum1 : dotNum2) + 1; if((dotNum1==0) && (dotNum2==0))//没有小数 { minusBitByBit(&a[0],&b[0],&c[0],resultLenMax-1-0+1,0); } else if(dotNum1==0)//被减数没小数,减数有小数 { shift=dotNum2; for(i=0;i<=dotNum2-1;i++) { c[i]=((0-b[i]-borrow)>=0) ? (0-b[i]-borrow):(0-b[i]-borrow+10); borrow=((0-b[i]-borrow)>=0) ? 0 : 1; } c[dotNum2]='.'-'0'; minusBitByBit(&a[dotNum2+1-shift-1],&b[dotNum2+1],&c[dotNum2+1],(resultLenMax-1)-(dotNum2+1)+1,borrow); } else if(dotNum2==0)//被减数有小数,减数没有小数 { shift=dotNum1; for(i=0;i<=dotNum1-1;i++) { c[i]=a[i]; } c[dotNum1]='.'-'0'; minusBitByBit(&a[dotNum1+1],&b[dotNum1+1-shift-1],&c[dotNum1+1],(resultLenMax-1)-(dotNum1+1)+1,borrow); } else if(dotNum1-dotNum2==0)//2个数都有小数,且小数位数相等 { minusBitByBit(&a[0],&b[0],&c[0],(dotNum1-1)-0+1,borrow); c[dotNum1]='.'-'0'; minusBitByBit(&a[dotNum1+1],&b[dotNum1+1],&c[dotNum1+1],(resultLenMax-1)-(dotNum1+1)+1,borrow); } else if(dotNum1-dotNum2<0)//2个数都有小数,减数位数多 { shift=dotNum2-dotNum1; for(i=0;i<=shift-1;i++) { c[i]=((0-b[i]-borrow)>=0) ? (0-b[i]-borrow):(0-b[i]-borrow+10); borrow=((0-b[i]-borrow)>=0) ? 0 : 1; } borrow=minusBitByBit(&a[0],&b[shift],&c[shift],(dotNum2-1)-(shift)+1,borrow); c[dotNum2]='.'-'0'; minusBitByBit(&a[dotNum2+1-shift],&b[dotNum2+1],&c[dotNum2+1],(resultLenMax-1+shift)-(dotNum2+1)+1,borrow); } else if(dotNum1-dotNum2>0)//2个数都有小数,被减数位数多 { shift=dotNum1-dotNum2; for(i=0;i<=shift-1;i++) { c[i]=((a[i]-0-borrow)>=0) ? (a[i]-0-borrow):(a[i]-0-borrow+10); borrow=((a[i]-0-borrow)>=0) ? 0 : 1; } borrow=minusBitByBit(&a[shift],&b[0],&c[shift],(dotNum1-1)-(shift)+1,borrow); c[dotNum1]='.'-'0'; minusBitByBit(&a[dotNum1+1],&b[dotNum1+1-shift],&c[dotNum1+1],(resultLenMax-1+shift)-(dotNum1+1)+1,borrow); } if(OK != intBitToSring(&c[0],sub, resultLenMax-1+shift)) return ERROR; return OK; } int bigDataAdd(char* sub1,char* sub2, char* sum) { int carry=0; int intNum1=0,intNum2=0,dotNum1=0,dotNum2=0,intBitNum,dotBitNum; int a[1000]={0},b[1000]={0},c[1000]={0}; char *nZero=NULL; IntDotInfo data1={0}; IntDotInfo data2={0}; char dotbuf1[512] = {0}; char buf1[1024] = {0}; char dotbuf2[512] = {0}; char buf2[1024] = {0}; if(OK != getIntDotInfo(sub1,sub2,&data1,&data2)) { return ERROR; } intNum1=data1.intNum; dotNum1=data1.dotPos; intNum2=data2.intNum; dotNum2=data2.dotPos; intBitNum=(intNum1>intNum2) ? intNum1 : intNum2; dotBitNum=(dotNum1>dotNum2) ? dotNum1 : dotNum2; nZero=(char *)malloc((dotBitNum+dotBitNum+1)*sizeof(char)); //先小位数对齐 if(dotNum1<=dotNum2) { alignNZero(dotBitNum-dotNum1,nZero); memset(dotbuf1, 0, sizeof(dotBitNum)); sprintf(dotbuf1,"%s%s",sub1,nZero); sprintf(dotbuf2,"%s",sub2); } else if(dotNum1>dotNum2) { alignNZero(dotBitNum-dotNum1,nZero); memset(dotbuf2, 0, sizeof(dotBitNum)); sprintf(dotbuf2,"%s%s",sub2,nZero); sprintf(dotbuf1,"%s",sub1); } //整数位对齐 if(intNum1<=intNum2) { alignNZero(dotBitNum-dotNum1,nZero); memset(buf1, 0, sizeof(intBitNum)); sprintf(buf1,"%s%s",nZero,dotbuf1); sprintf(buf2,"%s",dotbuf2); } else if(intNum1>intNum2) { alignNZero(dotBitNum-dotNum1,nZero); memset(buf2, 0, sizeof(intBitNum)); sprintf(buf2,"%s%s",nZero,dotbuf2); sprintf(buf1,"%s",dotbuf1); } stringToIntBit(buf1, &a[0]); stringToIntBit(buf2, &b[0]); carry=plusBitByBit(&a[0],&b[0],&c[0],dotBitNum,carry); c[dotBitNum]='.'-'0'; carry=plusBitByBit(&a[dotBitNum+1],&b[dotBitNum+1],&c[dotBitNum+1],intBitNum,carry); if(OK != intBitToSring(&c[0],sum, dotBitNum+1+intBitNum-1)) { return ERROR; } free(nZero); return OK; } char* sub(char* s1, char* s2) { int key=0; int p1,p2; memset(result,0,2 * MAX_DATA_LEN); p1=isPositive(s1); p2=isPositive(s2); if(p1 && p2) { key=stringValueCompare(s1,s2); if(key==1) { result[0]='-'; bigDataMinus(s2,s1,result+1); } else { bigDataMinus(s1,s2,result); } } else if(!p1 && !p2) { key=stringValueCompare(s1+1,s2+1); if(key==1) { bigDataMinus(s2+1,s1+1,result); } else { result[0]='-'; bigDataMinus(s1+1,s2+1,result+1); } } else if(p1 && !p2) { bigDataAdd(s1,s2+1,result); } else if(!p1 && p2) { bigDataAdd(s1+1,s2,result); } return result; } void unit_test() { assert(strcmp(sub("1","0"), "1") == 0); assert(strcmp(sub("100", "200"), "-100") == 0); assert(strcmp(sub("2222222.2222222","1111111.1111111"), "1111111.1111111") == 0); assert(strcmp(sub("2222222.2222222","-1111111.1111111"), "3333333.3333333") == 0); assert(strcmp(sub("10000000", "1.234"), "9999998.766") == 0); } void initData() { result=(char *)malloc(2 * MAX_DATA_LEN * sizeof(char)); if(NULL==result) { printf("malloc ERROR! "); } } void main() { initData(); unit_test(); free(result); }
原文地址:https://www.cnblogs.com/timssd/p/4019674.html