大数加减法
在计算机中,由于处理器位宽限制,只能处理有限精度的十进制整数加减法,比如在32位宽处理器计算机中,参与运算的操作数和结果必须在-231~231-1之间。如果需要进行更大范围的十进制整数加法,需要使用特殊的方式实现,比如使用字符串保存操作数和结果,采取逐位运算的方式。如下: 要求编程实现上述高精度的十进制加法。 代码如下: #include <stdio.h> #include <stdlib.h> #include <string.h> #define N 1000 /*去除前导0*/ int removeHeadZero(char *result,int lenRes) { int i; for (i=lenRes; result[i]!=' '; ++i) { if (result[i] != '0') { break; } } return i; } void bigMinusSmall(char *big,char *small,char sign) { int i,j,numBig,numSmall; int borrow = 0; int lenBig = strlen(big); int lenSmall = strlen(small); int lenRes = (lenBig > lenSmall) ? lenBig+2: lenSmall+2; /*减法位数不会增加,外加一个' '和负号'-'*/ char *result = (char *)malloc(sizeof(char)*lenRes); result[--lenRes] = ' '; for (i=lenBig-1,j=lenSmall-1; j>=0; --i,--j) { numBig = big[i] - '0'; numSmall = small[j] - '0'; if (numBig-borrow < numSmall) { result[--lenRes] = (10 + numBig - borrow - numSmall) + '0'; borrow = 1; } else { result[--lenRes] = (numBig - borrow - numSmall) + '0'; borrow = 0; } } for (; i>=0; --i) { numBig = big[i] - '0'; if (numBig - borrow < 0) { result[--lenRes] = (10 + numBig - borrow)+ '0'; borrow = 1; } else { result[--lenRes] = (numBig - borrow)+ '0'; borrow = 0; } } lenRes = removeHeadZero(result,lenRes); if (sign == '-') { result[--lenRes] = '-'; } printf("%sn",result+lenRes); free(result); result = NULL; } void minus(char *negative,char *positive) { int cmp; int lenNeg = strlen(negative); int lenPos = strlen(positive); if (lenNeg == lenPos) { cmp = strcmp(negative,positive); } else if (lenNeg > lenPos) { cmp = 1; } else { cmp = -1; } if (0 == cmp) { printf("0n"); } else if (cmp > 0) /*negative大*/ { bigMinusSmall(negative,positive,'-'); } else if (cmp < 0) /*positive大*/ { bigMinusSmall(positive,negative,'+'); } } void add(char *strA,char *strB,tmp; int carry = 0; int lenA = strlen(strA); int lenB = strlen(strB); int lenRes = (lenA > lenB) ? lenA+3: lenB+3; /*结果最多产生一位进位,外加一个' '和符号位*/ char *result = (char *)malloc(sizeof(char)*lenRes); result[--lenRes] = ' '; for (i=lenA-1,j=lenB-1; i>=0 && j>=0; --i,--j) { tmp = strA[i] - '0' + strB[j] - '0' + carry; carry = tmp / 10; result[--lenRes] = (tmp % 10) + '0'; } for (; i>=0; --i) { tmp = strA[i] - '0' + carry; carry = tmp / 10; result[--lenRes] = (tmp % 10) + '0'; } for (; j>=0; --j) { tmp = strB[j] - '0' + carry; carry = tmp / 10; result[--lenRes] = (tmp % 10) + '0'; } if (carry != 0) { result[--lenRes] = carry + '0'; } if (sign == '-') { result[--lenRes] = '-'; printf("%sn",result+lenRes); } else { printf("%sn",result+lenRes); } free(result); result = NULL; } int main(void) { char strA[N],strB[N]; while (scanf("%s%s",strA,strB) != EOF) { if (strA[0]=='-' && strB[0]=='-') /*都是负数时*/ { add(strA+1,strB+1,'-'); /*从1开始是为了跳过'-'*/ } else if (strA[0] == '-') { minus(strA+1,strB); /*第一个参数是负数串*/ } else if (strB[0] == '-') { minus(strB+1,strA); } else /*都是正数时*/ { add(strA,strB,'+'); /*都是正数*/ } } return 0; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |