设计一种结构能表示最多1000位的大整数,(正负均可),并实现这类数的加、减运算。
在座的各位程序员,下午五点就要交了,谢谢!
供参考:http://www.javashuo.com/article/p-nvngulti-nk.html
这是我以前写的算法,有点复杂凌乱,仅供参考!
#include<stdio.h>
#include<string.h>
//减法算法
char *sub(char *s1, char *s2);
//加法算法
char *add(char *s1, char *s2);
int main(int argc, char** argv){
char *res;//结果
int i=0;
char a[1000];//第一个操作数
char b[1000];//第二个操作数
printf("分别输入a,b\n");
printf("a=");
scanf("%s",a);
printf("\n");
printf("b=");
scanf("%s",b);
printf("\n输入运算符,加则输入1,减则输入2。\n");
scanf("%d",&i);
if(i==1)
{
res=add(a,b);
printf("(%s)+(%s)=%s\n",a,b,res);
}
else if(i==2)
{
res=sub(a,b);
printf("(%s)-(%s)=%s\n",a,b,res);
}
free(res);
return 0;
}
//加法算法
char *add(char *s1, char *s2)
{
int s1len=strlen(s1);
int s2len=strlen(s2);
int len1 = 0, len2 = 0;//对拷s1和s2并转换成数字后补齐位数后的长度,若是小数其实len1和len2的长度是一样的
int count1=0,count11=0;//分别是第一个数的小数部分长度 和 整数部分长度
int F1 = 0; //用于判断是否是小数,是小数F1=1,否则F1=0
for (int i = 0; i < s1len; i++)
{
if (*(s1 + i) == '.') { F1 = 1; break; }
}
//若是小数则 计算小数部分长度
for (int i = s1len - 1; i >= 0 && (F1 == 1); i--)
{
if (*(s1 + i) != '.')
count1++;
else
break;
}
//计算第一个加数的整数部分长度
count11 = (F1 == 1) ? (s1len - 1 - count1) : s1len;
//相同方法处理第二个加数
int count2 = 0, count22 = 0;
int F2 = 0;
for (int i = 0; i < s2len; i++)
{
if (*(s2 + i) == '.') { F2 = 1; break; }
}
for (int i = s2len - 1; i >= 0 && (F2 == 1); i--)
{
if (*(s2 + i) != '.')
count2++;
else
break;
}
count22 = (F2 == 1) ? (s2len - 1 - count2) : s2len;
len1 = (count1 > count2) ? count1 : count2;
int cc = len1;//用于后面标记小数的位置,这几行语句顺序不能颠倒
len1 += (count11 > count22) ? count11 : count22;
len2 = len1;
//为两个加数定义为a和b并为其动态分配内存空间
int *a = (int*)malloc(sizeof(int)*len1);
int *b = (int*)malloc(sizeof(int)*len2);
if (!a || !b)return "error";
//初始化a和b len1和len2其实是一样大的
for (int i = 0; i < len1; i++)
{
*(a + i) = 0;
*(b + i) = 0;
}
//定义和变量 以及取得长度
int len = len1 + 1;
int *sum = (int*)malloc(sizeof(int)*len);
if (!sum)return "error";
//初始化和变量
for (int i = 0; i < len; i++)*(sum + i) = 0;
int tt1 = count1 - count2;//用计算补齐几个0用
for (int i = s1len - 1, j = len1 - 1; j >= 0; i--, j--)
{
if (tt1 < 0)
{
while (tt1)
{
*(a + j--) = 0; tt1++;
}
}
if (*(s1 + i) == '.')i--;
if (i >= 0)
*(a + j) = *(s1 + i) - '0';
else
*(a + j) = 0;
}
int tt2 = count2 - count1;//用计算补齐几个0用
for (int i = s2len - 1, j = len2 - 1; j >= 0; i--, j--)
{
if (tt2 < 0)
{
while (tt2)
{
*(b + j--) = 0;
tt2++;
}
}
if (*(s2 + i) == '.')i--;
if (i >= 0)
*(b + j) = *(s2 + i) - '0';
else
*(b + j) = 0;
}
int cou = 0;
for (int i = len - 1, j = len1 - 1, k = len2 - 1; i >= 0; i--, j--, k--)
{
cou++;
if (cou <= len1)
{
*(sum + i) = *(a + j) + *(b + k);
}
else *(sum + i) = 0;
}
int temp1 = 0;
for (int i = len - 1; i >= 0; i--)
{
temp1 = *(sum + i);
*(sum + i) =*(sum + i) % 10;
if (i > 0)
*(sum + i - 1) += temp1 / 10;
}
//输出
char *sumres = (char*)malloc(sizeof(char)*(len+1));
if(!sumres)return "error!";
memset(sumres,'0',len+1);
int i,j;
for ( i = 0, j=0; i < len; i++,j++)
{
if( (F1 || F2) && ( i == (len - cc) ) )
{
*(sumres+i)='.';
j=i+1;
}
*(sumres+j)=(char)(*(sum+i)+'0');
}
*(sumres+j)='\0';
//释放
free(a);
free(b);
free(sum);
return sumres;
}
//减法算法
char *sub(char *s1, char *s2)
{
int abc = 1;//用于判断结果正负 负数abc赋值为-1
int s1len=strlen(s1);
int s2len=strlen(s2);
int len1 = 0, len2 = 0;//对拷s1和s2并转换成数字后补齐位数后的长度,若是小数其实len1和len2的长度是一样的
int count1 = 0, count11 = 0;//分别是第一个数的小数部分长度 和 整数部分长度
int F1 = 0; //用于判断是否是小数,是小数F1=1,否则F1=0
for (int i = 0; i < s1len; i++)
{
if (*(s1 + i) == '.') { F1 = 1; break; }
}
//若是小数则 计算小数部分长度
for (int i = s1len - 1; i >= 0 && (F1 == 1); i--)
{
if (*(s1 + i) != '.')
count1++;
else
break;
}
//计算第一个加数的整数部分长度
count11 = (F1 == 1) ? (s1len - 1 - count1) : s1len;
//相同方法处理第二个加数
int count2 = 0, count22 = 0;
int F2 = 0;
for (int i = 0; i < s2len; i++)
{
if (*(s2 + i) == '.') { F2 = 1; break; }
}
for (int i = s2len - 1; i >= 0 && (F2 == 1); i--)
{
if (*(s2 + i) != '.')
count2++;
else
break;
}
count22 = (F2 == 1) ? (s2len - 1 - count2) : s2len;
len1 = (count1 > count2) ? count1 : count2;
int cc = len1;//用于后面标记小数的位置,这几行语句顺序不能颠倒
len1 += (count11 > count22) ? count11 : count22;
len2 = len1;
//为两个加数定义为a和b并为其动态分配内存空间
int* a = (int*)malloc(sizeof(int)*len1);
int* b = (int*)malloc(sizeof(int)*len2);
if (!a || !b)return "error";
//初始化a和b len1和len2其实是一样大的
for (int i = 0; i < len1; i++)
{
*(a + i) = 0;
*(b + i) = 0;
}
//定义结果变量c 以及取得长度
int len = len1 ;
int* c= (int*)malloc(sizeof(int)*len);
if (!c)return "error";
//初始化和变量
for (int i = 0; i < len; i++)*(c + i) = 0;
int tt1 = count1 - count2;//用计算补齐几个0用
for (int i = s1len - 1, j = len1 - 1; j >= 0; i--, j--)
{
if (tt1 < 0)
{
while (tt1)
{
*(a + j--) = 0; tt1++;
}
}
if (*(s1 + i) == '.')i--;
if (i >= 0)
*(a + j) = *(s1 + i) - '0';
else
*(a + j) = 0;
}
int tt2 = count2 - count1;//用计算补齐几个0用
for (int i = s2len - 1, j = len2 - 1; j >= 0; i--, j--)
{
if (tt2 < 0)
{
while (tt2)
{
*(b + j--) = 0;
tt2++;
}
}
if (*(s2 + i) == '.')i--;
if (i >= 0)
*(b + j) = *(s2 + i) - '0';
else
*(b + j) = 0;
}
//-------------------
//判断a与b的大小,大数作为第一个数
int a1 = 0, b1 = 0;//用于判断a和b哪个大大的就赋值为1
for (int i = 0; i < len1; i++)
{
int tmp=*(a + i) - *(b + i);
if (tmp > 0)
{
a1 = 1; break;
}
else if (tmp < 0)
{
b1 = 1;
abc = -1;
break;
}
//如果循环结束a1==0 && b1==0表示a和b相等 结果直接为0即可
}
//a>=b时情况
int cou = 0;
if((a1 == 1) || (a1 == 0 && b1 == 0))
for (int i = len - 1, j = len1 - 1, k = len2 - 1; i >= 0; i--, j--, k--)
{
int vv = 0; //是否借位的记号 借位赋值1
int n = 0;//借位移动了几位
cou++;
int tmp1= *(a + j) - *(b + k);
if (cou <= len1 )
{
if(tmp1>=0)
{
*(c + i) = tmp1;
}
else//向高位(低索引处借位)
{
tmp1 += 10;
*(c + i) = tmp1;
vv = 1;
}
}
else *(c + i) = 0;
//处理借位
if (vv == 1)
for (int ccc = j-1;ccc >= 0 && j>0;ccc--)
{
if (*(a + ccc) == 0)n++;
else
break;
}
if (vv == 1)
for (int bb = n; bb<j && bb>0; bb--)
{
*(a +j-bb) += 9;
}
//借位处减去1
if (vv == 1 && j >= (n + 1))
*(a + (j - n - 1)) -= 1;
//重置
vv = 0;
n = 0;
}
//a<b情况
int cou2 = 0;
if ((b1 == 1))
for (int i = len - 1, j = len1 - 1, k = len2 - 1; i >= 0; i--, j--, k--)
{
int vv = 0; //是否借位的记号 借位赋值1
int n = 0;//借位移动了几位
cou2++;
int tmp1 = *(b + k)-*(a + j) ;
if (cou2 <= len2)
{
if (tmp1 >= 0)
{
*(c + i) = tmp1;
}
else//向高位(低索引处借位)
{
tmp1 += 10;
*(c + i) = tmp1;
vv = 1;
}
}
else *(c + i) = 0;
//处理借位
if(vv==1)
for (int ccc = j - 1; ccc >= 0 && j>0; ccc--)
{
if (*(b+ ccc) == 0)n++;
else
break;
}
if (vv == 1)
for (int bb = n; bb<k && bb>0; bb--)
{
*(b +k - bb ) += 9;
}
//借位处减去1
if (vv == 1 && k>=(n+1) )
*(b + (k - n - 1)) -= 1;
//重置
vv = 0;
n = 0;
}
char *resc= (char*)malloc(sizeof(char)*(len+1));
if(!resc)return "error!";
memset(resc,'0',len+1);
//输出
int i,j;
for (i = 0,j=0; i < len; i++,j++)
{
if(abc==-1)
{
*(resc+j++)='-';
abc = 1;
}
if((F1 || F2) && (i == (len - cc)))
{
*(resc+j++)='.';
}
*(resc+j)=(char)(*(c + i)+'0');
}
*(resc+j)='\0';
//释放
free(a);
free(b);
free(c);
return resc;
}