题目
在数学运算过程中,经常碰到参与运算的数字很大或者对运算结果的精度要求很高的问题。
在上述情况下,采用一般的程序设计无法满足要求,必须采用高精度的数学运算才能实现。
作为实现大数存储最常见的一类方法是利用数组。将一个有n位的大数存入数组,每个数组的一个元素表示一位十进制数,再按十进制由低到高逐位相加,同时考虑进位。
方法一:
(1)将A、B按位对齐
(2)低位开始逐位相加
(3)对结果做进位调整
分析:
(1)将和整除以10,余数就是该位的结果,并转换为字符(整型数据+48)存入改位,商就是进位数。
(2)从最低位对应的数组元素开始将数字字符转换为整型数据相加,因为数字字符‘0’对应的ASCII值是48,则整型数据1+2相当于(‘1’ - 48)+(‘2’ - 48)
代码:
#include<stdio.h>
#include<string.h>
int main() {
char a[201], b[201]; //最长200位
int i, j, k, m, n;
scanf("%s", a);
scanf("%s", b);
m = strlen(a);
k = n = strlen(b);
if (m > k) //k是两个字符串长度的最大值
k = m;
a[k + 1] = 0; //为了存储最高位的进位,位数多的数最高位前夜应补一个0
for (i = 0; i < k; i++)
a[k - i] = a[m - i - 1]; //使数组a的字符串以a[k]右对齐
for (i = 0; i <= k - m; i++)
a[i] = '0'; //使数组a的高位补0
for (i = 0; i < k; i++)
b[k - i] = b[n - i - 1]; //使数组b的字符串以b[k]右对齐
for (i = 0; i <= k - n; i++)
b[i] = '0'; //使数组b的高位补0
j = 0; //进位
for (i = 0; i < k; i++) {
j = (a[k - i] + b[k - i] + j - 96); //数字字符转换为整型数据相加
a[k - i] = j % 10 + 48;
j = j / 10; //取出相加和整除的商,作为本位的进位数
}
if (a[0] == '0')
printf("%s\n", a + 1);
else
printf("%s\n", a);
return 0;
}
方法二:
(1)三个数组a,b,c。a与b为加数,c为和。
(2)将a b倒序
(3)从a[0] b[0]开始进行求和
(4)倒序输出
代码
#include<stdio.h>
#include<string.h>
int main() {
int i, j = 0, len1, len2;
char a[201], b[201];
char c[201];
gets(a);
gets(b);
len1 = strlen(a);
len2 = strlen(b);
for (i = 0; i < len1 / 2; i++) { //a、b倒序
int t = a[i];
a[i] = a[len1 - 1 - i];
a[len1 - 1 - i] = t;
}
for (i = 0; i < len2 / 2; i++) {
int t = b[i];
b[i] = b[len2 - 1 - i];
b[len2 - 1 - i] = t;
}
int ad = 0; //进位
while (j < len1 && j < len2) {
c[j] = (a[j] + b[j] - 96 + ad) % 10;
ad = (a[j] + b[j] - 96 + ad) / 10;
j++;
}
//a比b长
if (j < len1) {
c[j] = (a[j] - '0' + ad) % 10;
ad = (a[i] - '0' + ad) / 10;
j++;
}
else if (j < len2){ //b比a长
c[j] = (b[j] - '0' + ad) % 10;
ad = (b[i] - '0' + ad) / 10;
j++;
}
//判断最高位
if (ad > 0)
c[j++] = ad;
for (int k = j - 1; k >= 0; k--) //倒序输出
printf("%d", c[k]);
return 0;
}