关于高精度加法
题目:
由键盘输入两个位数很长的整数(一行一个,最多不超过80位),试计算并输出这两个数的和。
输入样例
1234567890123456789353534532453453453434534
987654321098765324534534534534532
输出样例
1234567891111111110452299856987987987969066
引入
学过
C
C
C语言的我们,对于普通的加法当然会算,就是简单的输入
a
a
a和
b
b
b,然后输出
a
+
b
a+b
a+b就行
#include <stdio.h>
int main()
{
int a, b;
scanf("%d%d",&a, &b);
printf("%d\n",a + b);
return 0;
}
那么,当 a a a的值很大很大,且b的值也很大很大的时候呢?
就是当
a
a
a为
1234567890123456789353534532453453453434534
1234567890123456789353534532453453453434534
1234567890123456789353534532453453453434534
b
b
b为
987654321098765324534534534534532
987654321098765324534534534534532
987654321098765324534534534534532
时。
相信大家一开始看到这一长串的数字,肯定都蒙了吧!
正常一个普通的变量是存不了
10
10
10几位的数字的。
那么这时候我们应该怎么解决这样的问题呢?
没错,这时候就要用上我们所学的数组了,但要记住,不是单纯的数组,是字符串数组和普通数组一起使用。下面一步一步的进行讲解。
大数在字符串数组是怎样存取的
将字符转化为整形数字存入数组
这里要记住一定要倒序存储,字符数组存储的是字符对应的ASCII码,所以当我们将字符转化为数字时要减去 0 0 0**或者 48 48 48( 0 0 0对应的 A S C I I ASCII ASCII码)
int i,j,k,len1,len2,len;
char k1[100],k2[100];
int m1[100],m2[100],m[101];/*这里建立三个整形数组,其中两个存取大整数,另外一个存取两个数相加后的大整数*/
//因为我们最后一位有可能需要向下一位进1,所以我们建立数组的时候,存取结果的数组要比存取加数的要多一位,才能保证最后不会越界。
scanf("%s",k1);
scanf("%s",k2);
len1=strlen(k1);//"strlen"是一个计算字符串长度的函数
len2=strlen(k2);//将输入的两个字符串的长度赋值给len1,len2
for(i=0; i<len1; i++)
{
m1[i]=k1[len1-1-i]-'0';//很常规的倒序存储,一定要记得减'0'
}
for(i=0; i<len2; i++)
{
m2[i]=k2[len2-1-i]-'0';
}
经过倒序存储后, 123456789 123456789 123456789就会变成“ 987654321 987654321 987654321”存进数组中
接下来是最重要的就是计算
记住一个最重要的原则“满10向下一位进1”
比如
23456789
+
98765432
23456789+98765432
23456789+98765432
因为已经倒序存过数字了,所以直接从最高位开始计算,即
2
+
9
=
11
2+9=11
2+9=11;这时候因为已经满
10
10
10了,所以我们要向下一位进
1
1
1,即当我们计算下一位的时候最后要加上1,并且该位要
−
10
-10
−10;若未满
10
10
10,就保留数字即可,并且将数字存进一个新的数组。
最后依次计算可得两数之和为
122222221
122222221
122222221
if(len2>=len1)
{
for(i=len2; i<len2; i++)
{
m1[i]=0;
}
len=len2;
}
k=0;//这里的k是指是否要向下一位进1,k=0为不需要进1,k=1为需要
for(j=0; j<len; j++)//依次进行每一位的加法,满十进一
{
m[j]=m1[j]+m2[j]+k;
if(m[j]>=10)//判断是否需要向下一位进1
{
k=1;
m[j]=m[j]-10;
}
else
{
k=0;
}
if(j==len-1&&k==1)//这里,如果已经计算到最后一位了,且这时需要进一,我们便往下一位填1即可
{
j++;
m[j]=k;
}
}
for(i=j-1; i>=0; i--)//最后再倒序输出新数组内的数字即为最后的结果
{
printf("%d",m[i]);
}
}
完整解题代码
#include <stdio.h>
#include <string.h>
int main()
{
int i,j,k,len1,len2,len;
char k1[100],k2[100];
int m1[100],m2[100],m[101];
scanf("%s",k1);
scanf("%s",k2);
len1=strlen(k1);
len2=strlen(k2);
for(i=0; i<len1; i++)
{
m1[i]=k1[len1-1-i]-'0';
}
for(i=0; i<len2; i++)
{
m2[i]=k2[len2-1-i]-'0';
}
if(len1>len2)
{
for(i=len2; i<len1; i++)
{
m2[i]=0;
}
len=len1;
}
if(len2>=len1)
{
for(i=len2; i<len2; i++)
{
m1[i]=0;
}
len=len2;
}
k=0;
for(j=0; j<len; j++)
{
m[j]=m1[j]+m2[j]+k;
if(m[j]>=10)
{
k=1;
m[j]=m[j]-10;
}
else
{
k=0;
}
if(j==len-1&&k==1)
{
j++;
m[j]=k;
}
}
for(i=j-1; i>=0; i--)
{
printf("%d",m[i]);
}
}
总结
高精度加法是一个很有难度的题,并且会延伸出类似于二进制加法,甚至八进制加法的题目,所以一定要总结规律,以后类似的题目就能迎刃而解了。