c语⾔实现两个超⼤数的相加(超长数据
这⼏天⽆聊,突然想起来,⼤学当时有个问题困扰着我
两个超⼤的数怎么保存和相加呢,计算机的整形32位的最⼤也就4294967296,超过这个数就计算不了了哇
然后就想动⼿实践⼀下
思路:
1.超长数据怎么存呢。脑⼦⼀拍,巨长的数肯定⽤字符数组来存哇,没⽑病。
2.要怎么运算呢。我想的是,⼀个数最⼤是4294967296,长度为10,那我两个9长度的数据相加,肯定不会超过1999999998,那我就把巨长的字符数组每九个切割成整形数组保存起来呗,这样就可以相加了。⽐如
111111111222222222+3333333333444444444转化为111111111+3333333333和222222222+444444444然后把两个结果凑⼀起就成啦
3.嗯,这样的思路看起来没⽑病,挺简单的。(MDZZ,对⾃⼰竖中指,真蠢的办法,代码写⼀半想到了更简单的⽅法,结尾说说)。那就动⼿吧。
代码:
ps:代码有点长,没办法,太傻了,写起来才发现,这种⽅法要考虑好多种情况,⽐如连续进位,两个数据不等长等等
#include<stdio.h>
//将字符数据转换成int类型数据,9个长度的为⼀个数据,调⽤atoi函数变为整形
//例如123456789087654321->第⼀个数据为087654321第⼆个数据为123456789
//倒着读⼊并转换成整形的
int convert(char *data,int *temp)
{
int lenth=strlen(data);//获取输⼊数据长度
int i=0,j=0,k=0;//i控制循环,从数据最后⼀个数据往前循环
//j控制分割字符保存⼊temp_data
//k⽤来返回数据转换了多少个9长度的整形数据
char temp_data[9];//中间变量,存分割出来的9个字符
for(i=lenth-1;i>=0;i--)
{
temp_data[8-j] = data[i];
j++;
if(j==9)
{
j=0;
temp[k]=atoi(temp_data);//转换成整形数据存⼊temp
k++;
memset(temp_data,0,sizeof(temp_data));
}
}
if(lenth%9 == 0)
return k-1;
while(j<9)//如果最后⼀个数据长度⼩于9,就填充0
{
temp_data[8-j] = '0';
j++;
}
temp[k]=atoi(temp_data);//最后⼀个数据
return k;
}
//计算函数,传参,
//第⼀个数据的整形数组
//数组使⽤长度
//第⼀个数据的整形数组
//数组使⽤长度
//结果保存整形数组
int calc(int *data1,int dw1,int *data2,int dw2,int *result)
int calc(int *data1,int dw1,int *data2,int dw2,int *result)
{
int i=0,j=0,k=0,diff=0,diff_result=0,jw=0;//i,j控制循环读⼊数据1和数据2的数据
//k控制result数组长度
//diff为数据1与1000000000的差值,diff_result是数据2与diff的差值
//jw标志是否进位
for(i=0,j=0;i<=dw1&&j<=dw2;i++,j++)
{
result[k]=data1[i];
diff = 1000000000 - data1[i];
diff_result = data2[j] - diff;
if (diff_result > 0)//代表需要进位
{
result[k]=diff_result+jw;
jw=1;
}
else//⽆需进位
{
result[k]+=data2[j]+jw;
jw=0;
}
k++;
}
while(i<=dw1)//数据1长度⽐数据2长时接下来的数据处理
{
if(jw==1) //之前的数据是否有进位
{
if(data1[i]+1 >= 1000000000)//如果进位超过了1000000000,例如9999999999+111111111111    {
result[k]=0;
k++;
i++;
jw=1;
continue;
}
result[k]=data1[i]+1;
jw=0;
}
else
result[k]=data1[i];
k++;
i++;
}
while(j<=dw2)//数据2长度⽐数据1长时接下来的数据处理
{
if(jw==1)//之前的数据是否有进位
{
if(data2[j]+1 >= 1000000000)//如果进位超过了1000000000,例如9999999999+111111111111  {
result[k]=0;
k++;
j++;
jw=1;
continue;
}
result[k]=data2[j]+1;
jw=0;
}
else
result[k]=data2[j];
k++;
j++;
}
if(jw==1)
{
result[k]=1;
k++;
}
return k-1;//返回结果的整形数组存⼊数据的个数
}
int main()
{
char data1[100]={0,};//存第⼀个输⼊的数据,最长数据99位哟
char data2[100]={0,};//存第⼆个输⼊的数据,最长数据99位哟
int temp1[11]={0};//存第⼀个数据转化为整形的数据
int temp2[11]={0};//存第⼆个数据转化为整形的数据
int result[11]={0};//存结果的整形数据
int dw1=0,dw2=0,result_dw=0;//数组下标,对应数据1,2和结果
int i=0;//控制结果打印的循环
printf("input data1:");
gets(data1);
dw1=convert(data1,temp1);//数据1转化为整形数组
printf("input data2:");
gets(data2);
dw2=convert(data2,temp2);//数据2转化为整形数组
result_dw=calc(temp1,dw1,temp2,dw2,result);//计算
printf(">result:");
for(i=result_dw;i>=0;i--)两个傻子在一起
{
if(i==result_dw)
printf("%d",result[i]);//开头数据不⽤0补齐
else
printf("%09d",result[i]);
}
printf("\n");
return 0;
}
这段代码写了我⼀个半⼩时,
半⼩时以为⾃⼰写完了
运⾏,有bug,不等长数据计算错误,转换有问题,显⽰有问题......
半⼩时以后以为⾃⼰写完了
运⾏,有bug,进位有问题,连续进位有问题......
半⼩时以后以为⾃⼰写完了
嗯,应该是写完了,没测出啥错误了,哭
原谅⼀个计算机萌新。。。不。。我都⼯作五个⽉了,写这种代码⽤了快两个⼩时,我对⾃⼰是个程序员表⽰羞愧,想去屎。
写到⼀半,写calc计算函数时候,我脑⼦⾥⼀闪,我为什么不直接让两个数据⼀个字符⼀个字符的相加,直接data1[n]+data2[n]-'0'-'0'不就⾏了嘛,在搞个标志看是否进位。。。。。。⽐我之前的想法简单多了,别拉我,让我去屎,不论从哪个⽅⾯看,算法,复杂度(这玩意我也不是很了解哈哈),看着我写的代码都像个傻⼦QAQ。
如果我想实践我后来的想法再写吧。完