直接贴代码,看注释:
#include <stdio.h>
#include <stdlib.h>
// 最大一百位数的加减法实现
const int MAXSIZE = 100;
typedef struct {
int length; //长度
int numbers[MAXSIZE]; //各个位上的数字,从低位数字到高位数字
int sign; //符号:0代表正数,1代表负数,规定0的符号为正
}SqList;
//头插,即新元素插入到numbers[0]
void insert(SqList *l, int x)
{
SqList *p = l;
if(l->length<MAXSIZE){
int i;
//所有后移
for(i=l->length-1;i>=0;i--){
l->numbers[i+1]=l->numbers[i];
}
l->numbers[0] = x;
l->length++;
}
}
//初始化: s:符号,0正1负;a:包含从高位到低位各个位数的数组;n:位数,也即数组a的长度
SqList *init(int s, int *a, int n)
{
SqList *L;
L=(SqList*)malloc(sizeof(SqList));
if(!L)
{
printf("Init Error!");
exit(1);
}
L->sign=s;
L->length=0;
int i;
for(i=0;i<n;i++){
insert(L,a[i]);
}
return L;
}
void log(SqList *l){
if(l!=NULL){
printf("-------------\n");
printf("length: %d\n",l->length);
printf("sign: %d\n", l->sign);
printf("numbers: ");
int i=0;
for(i=l->length-1;i>=0;i--){
printf("%d ", l->numbers[i]);
}
printf("\n");
}
}
// 简单的正数相加
SqList *add(SqList *l1, SqList *l2){
SqList *l = init(0,0,0);
int c = 0; //进位
int i;
int t; //temp value for sequence add.
int len = (l1->length>l2->length)?l2->length:l1->length;
//按照加法逻辑,从低位到高位开始相加
for(i=0;i<len;i++){
t = l1->numbers[i] + l2->numbers[i] + c;
l->numbers[i] = t%10;
l->length++;
if(t>=10){
c = t/10;
}else{
c = 0;
}
}
//按照加法逻辑,以下处理较大数字的高位
len = l1->length-l2->length;
len = (len<0)?-len:len;
len = len+i;
for(i;i<len;i++){
printf("true\n");
int t;
if(l1->length>l2->length){
t = l1->numbers[i] + c;
}else{
t = l2->numbers[i] + c;
}
l->numbers[i] = t%10;
l->length++;
if(t>=10){
c = t/10;
}else{
c = 0;
}
}
return l;
}
// 简单的正数相减,不论顺序,永远返回较大数减去较小数的值
SqList *sub(SqList *l1, SqList *l2){
SqList *l = init(0,0,0);
int c = 0; // 借位
int i;
int t;
int len = (l1->length>l2->length)?l2->length:l1->length;
//按照减法逻辑,从低位到高位开始相减
for(i=0;i<len;i++){
if(l1->length>l2->length){
if((l1->numbers[i]-c)<l2->numbers[i]){
t = l1->numbers[i]+10 - l2->numbers[i] - c;
c = 1;
}else{
t = l1->numbers[i] - l2->numbers[i] - c;
c = 0;
}
}else{
if((l2->numbers[i]-c)<l1->numbers[i]){
t = l2->numbers[i]+10 - l1->numbers[i] - c;
c = 1;
}else{
t = l2->numbers[i] - l1->numbers[i] - c;
c = 0;
}
}
l->numbers[i] = t%10;
l->length++;
}
//处理较大数的高位
len = l1->length-l2->length;
len = (len<0)?-len:len;
len = len+i;
for(i;i<len;i++){
int t;
if(l1->length>l2->length){
t = l1->numbers[i] - c;
}else{
t = l2->numbers[i] - c;
}
//如果和借位相减为0,得数应该减少一位
if(t==0){
l->length--;
}
l->numbers[i] = t%10;
l->length++;
if(t<0){
c = 1;
}else{
c = 0;
}
}
return l;
}
//绝对值比较,用于真正的加减运算判断
int cmpabs(SqList* l1, SqList *l2){
if(l1->length!=l2->length){
return (l1->length>l2->length)?(1):(0);
}else{
int i;
for(i=l1->length-1;i>=0;i--){
if(l1->numbers[i]>l2->numbers[i]){
return 1;
}else if(l1->numbers[i]<l2->numbers[i]){
return 0;
}
}
return 2;
}
}
//加法,判断两数符号做相应处理
SqList* ADD(SqList* l1, SqList* l2){
if(l1->sign == 0 && l2->sign == 0){
return add(l1,l2);
}else if(l1->sign == 1 && l2->sign == 1){
SqList* l = add(l1,l2);
l->sign = 1;
return l;
}else{
SqList* l = sub(l1,l2);
l->sign = !cmpabs(l1,l2);
return l;
}
}
//减法,判断两数符号做相应处理,较加法而言还要考虑操作数顺序
SqList* SUB(SqList* l1, SqList* l2){
int t = cmpabs(l1,l2);
if(t == 2){
int a[1] = {0};
SqList* l = init(0,a,1);
return l;
}
if(l1->sign == 1 && l2->sign == 1){
if(t == 0){
return sub(l1,l2);
}else if(t == 1){
SqList* l = sub(l1,l2);
l->sign = 1;
return l;
}
}else if(l1->sign == 0 && l2->sign == 0){
if(t == 1){
return sub(l1,l2);
}else if(t == 0){
SqList* l = sub(l1,l2);
l->sign = 1;
return l;
}
}else if(l1->sign == 1 && l2->sign == 0){
SqList* l = add(l1,l2);
l->sign = 1;
return l;
}else if(l1->sign == 0 && l2->sign == 1){
return add(l1,l2);
}
}
int main()
{
printf("Application starts...\n");
int a1[3] = {1,2,2};
SqList *l1 = init(1, a1, 3);
log(l1);
int a2[2] = {2,4};
SqList *l2 = init(0, a2 ,2);
log(l2);
SqList *l3 = init(1, a2 ,2);
SqList *l = SUB(l2,l1);
log(l);
return 0;
}