高精度数加法运算的进位问题
知识目标
- 学习高精度数加法运算的进位。高精度数的加法运算——进阶高精度数的加法运算
【问题描述】
输入两个高精度数,输出这两个数的和(两个高精度数位数不一定相同且可能存在进位)。
【样例输入 1】 9999900000
123456789
【样例输出 1】 10123356789
【样例输入 2】 123456789
123456789
【样例输出 2】 246913578
解题思路:
- 1、读入两个大数存入两个字符串中
- 2、求出大数的长度
- 3、将字符类型转换为数字类型倒序存入整型数组中
- 4、将两个整型数组中对应位数字相加存入整型数组中,并处理进位
- 5、判断最高进位是否为 0
- 6、倒序输出
【过程分析】
对此类型的题我们总结方法如下:
两个高精度数的加法:倒序补 0,对应位相加,处理进位,倒序输出。
第一步:定义两个字符型数组 a1,b1 用来存储进行相加的两个高精度数,定义整型数组a,b,c 分别用来存储两个高精度数的数字和相加后得到的数字,定义整型变量 lena,lenb, i 分别表示相加的两个数的位数及循环变量,定义整型变量 lenc,x 分别表示两个高精度数相加后的数的位数长度和进位,对 lenc 和 x 赋初始值为 0;
char a1[1001]= {},b1[1001]= {};
int a[1001]= {},b[1001]= {},c[1001]= {},lena,lenb,i;
int lenc = 0,x = 0;
第二步:输入两个高精度数,并分别求出两个高精度数的长度;
cin>>a1>>b1;
lena = strlen(a1);
lenb = strlen(b1);
第三步:使用 for 循环遍历,分别将存储在字符数组里的被加数和加数字符串转换为数字, 并倒序储存到整型数组里;
for(i = 0; i <= lena-1; i++) {
a[lena-i-1] = a1[i] - 48;
}
for(i = 0; i <= lenb -1; i++) {
b[lenb-i-1] = b1[i] - 48;
}
第四步:使用 while 循环语句对各个数位上的数求和,满足相加得到的位数小于 a 的长度或者 b 的长度时,执行循环语句,每次循环的过程中将 a 和 b 对应位的数相加并加上进位 x 的值,得到对应数位的数存储在 c 数组中,因为得到的数可能超过 10,因此计算完后需要进行进位 x 值的更新,并用该数对 10 取余得到该位上的数;
while(lenc<lena||lenc<lenb) {
c[lenc]=a[lenc]+b[lenc]+x;
x = c[lenc]/10;
c[lenc] = c[lenc]%10;
lenc++;
}
第五步:使用 if 语句判断三个高精度最高位相加的进位 x 是否不为 0,成立则赋值给相加和的最高位,不成立则 lenc 减 1,去掉前导 0;
if(x){
c[lenc]=x;
}else{
lenc--;
}
第六步:使用 for 循环语句进行倒序输出各个数位上的数即为最后的正确结果。
for( i = lenc; i >= 0; i--){
cout << c[i];
}
完整代码:
#include <iostream>
#include <cstring>
using namespace std;
int main() {
char a1[1001]= {},b1[1001]= {};
int a[1001]= {},b[1001]= {},c[1001]= {},lena,lenb,i;
int lenc = 0, x = 0;
cin>>a1>>b1;
lena = strlen(a1);
lenb = strlen(b1);
for(i = 0; i <= lena-1; i++) {
a[lena-i-1] = a1[i] - 48;
}
for(i = 0; i <= lenb -1; i++) {
b[lenb-i-1] = b1[i] - 48;
}
while(lenc<lena||lenc<lenb) {
c[lenc]=a[lenc]+b[lenc]+x;
x = c[lenc]/10;
c[lenc] = c[lenc]%10;
lenc++;
}
if(x){
c[lenc]=x;
}else{
lenc--;
}
for(i = lenc;i >=0;i--){
cout << c[i];
}
return 0;
}
高精度数的运算:
【问题描述】输入三个高精度数,计算他们的和并输出(没有进位)。
【输入样例】
111111111111111111111
222222222222222222222
17
【输出样例】
333333333333333333350
解题思路:
- 1、读入三个大数存入三个字符串中
- 2、将字符类型转换为数字类型存入整型数组中
- 3、首先计算前两个高精度数的和,存储在第一个整形数组中,然后计算第一个整形数组和第三个整形数组的和,保存在第一个整形数组中
- 4、输出第一个整形数组
【过程分析】
第一步:定义三个字符型数组 a1,b1,c1 用来存储进行相加的三个高精度数,定义整型数组a,b,c,d 分别用来存储三个高精度数的数字和三个数相加和,定义整型变量lena,lenb, lenc,i 分别表示相加的三个数的位数及循环变量,定义整型变量 len,x 分别表示三个高精度数相加后的数的位数长度和进位,对 lenc 和 x 赋初始值为 0;
char a1[1001]={},b1[1001]={},c1[1001]={};
int a[1001]={},b[1001]={},c[1001]={},d[1001]={};
int x=0,len=0,lena,lenb,lenc;
第二步:输入三个高精度数,并分别求出三个高精度数的长度;
cin>>a1>>b1>>c1; lena = strlen(a1);
lenb = strlen(b1);
lenc = strlen(c1);
第三步:使用 for 循环遍历,分别将存储在字符数组里的被加数和加数字符串转换为数字, 并倒序储存到整型数组里;
for(i = 0; i <= lena-1; i++) {
a[lena-i-1] = a1[i] - 48;
}
for(i = 0; i <= lenb -1; i++) {
b[lenb-i-1] = b1[i] - 48;
}
for(i = 0; i <= lenc -1; i++) {
c[lenc-i-1] = c1[i] - 48;
}
第四步:使用 while 循环语句对各个数位上的数求和,满足相加得到的位数小于 a 的长度或者 b 的长度或者 c 的长度时,执行循环语句,每次循环的过程中将 a 和 b 对应位的数相加并加上进位 x 的值,得到对应数位的数存储在 c 数组中,因为得到的数可能超过 10,因此计算完后需要进行进位 x 值的更新,并用该数对 10 取余得到该位上的数;
while(len<lena||len<lenb||len<lenc) {
d[len]=a[len]+b[len]+c[len]x;
x = d[len]/10; d[len] = d[len]%10;
len++;
}
第五步:使用 if 语句判断三个高精度最高位相加的进位 x 是否不为 0,成立则赋值给相加和的最高位,不成立则 len 减 1,去掉前导 0;
if(x){
d[len] = x;
}else{
len--;
}
第六步:使用 for 循环语句进行倒序输出各个数位上的数即为最后的正确结果;
for( i=len;i >=0;i--){
cout << d[i];
}
完整代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int main(){
char a1[1001]={},b1[1001]={},c1[1001]={};
int a[1001]={},b[1001]={},c[1001]={},d[1001]={};
int x=0,len=0,lena,lenb,lenc,i;
cin>>a1>>b1>>c1;
lena = strlen(a1);
lenb = strlen(b1);
lenc = strlen(c1);
for(i = 0; i <= lena-1; i++) {
a[lena-i-1] = a1[i] - 48;
}
for(i = 0; i <= lenb -1; i++) {
b[lenb-i-1] = b1[i] - 48;
}
for(i = 0; i <= lenc -1; i++) {
c[lenc-i-1] = c1[i] - 48;
}
while(len<lena || len<lenb || len<lenc) {
d[len] = a[len] + b[len] + c[len] + x;
x = d[len]/10;
d[len] = d[len]%10;
len++;
}
if(x){
d[len] = x;
}else{
len--;
}
for( i=len;i >=0;i--){
cout << d[i];
}
return 0;
}
模拟乘法:
【问题描述】输入一个高精度数,输出他的两倍的值是多少?
【输入样例】
1111111111111111111111111115
【输出样例】
2222222222222222222222222230
【过程分析】
第一步:定义一个字符型数组 a1 用来存储进行相加的一个高精度数,定义整型数组 a,b 分别用来存储高精度数的数字和数字 2 倍的值,定义整型变量 lena,i 分别表示相加的三个数的位数及循环变量,定义整型变量 len,x 分别表示三个高精度数相加后的数的位数长度和进位,对 len 和 x 赋初始值为 0;
char a1[1001]={};
int a[1001]={},b[1001]={};
int x=0,len=0,lena;
第二步:输入一个高精度数;
cin>>a1;
lena = strlen(a1);
第三步:使用 for 循环遍历,分别将存储在字符数组里的被加数和加数字符串转换为数字, 并倒序储存到整型数组里;
for(i = 0; i <= lena-1; i++) {
a[lena-i-1] = a1[i] - 48;
}
第四步:使用 while 循环语句对各个数位上的数求和,满足相加得到的位数小于 a 的长度或者 b 的长度或者 c 的长度时,执行循环语句,每次循环的过程中将 a 和 b 对应位的数相加并加上进位 x 的值,得到对应数位的数存储在 c 数组中,因为得到的数可能超过 10,因此计算完后需要进行进位 x 值的更新,并用该数对 10 取余得到该位上的数;
while(len<lena) {
b[len]=a[len]+a[len]+x; x = b[len]/10;
b[len] = b[len]%10; len++;
}
第五步:使用 if 语句判断三个高精度最高位相加的进位 x 是否不为 0,成立则赋值给相加和的最高位,不成立则 len 减 1,去掉前导 0;
if(x){
b[len] = x;
}else{
len--;
}
第六步:使用 for 循环语句进行倒序输出各个数位上的数即为最后的正确结果;
for( i=len;i >=0;i--){
cout << b[i];
}
完整代码:
#include <iostream>
#include <cstring>
using namespace std;
int main (){
char a1[1001]={};
int a[1001]={},b[1001]={};
cin >> a1;
int lena = strlen(a1);
int x=0,len=0;
for (int i=0;i<=lena-1;i++){
a[lena-1-i] = a1[i] - 48;
}
while(len<lena){
b[len]=a[len]+a[len]+x;
x=b[len]/10;
b[len] = b[len]%10; len++;
}
if(x){
b[len] = x;
}else{
len--;
}
for(int i=len;i>=0;i--){
cout <<b[i];
}
return 0;
}
求高精度数相加的进位次数:
【问题描述】
输入两个高精度数,输出他们相加时的进位次数
【样例输入】
11111111111111111
92222222222222219
【样例输出】
2
【过程分析】
第一步:定义两个字符型数组 a1,b1 用来存储进行相加的两个高精度数,定义整型数组a,b,c 分别用来存储两个高精度数的数字和相加后得到的数字,定义整型变量 lena,lenb, i 分别表示相加的两个数的位数及循环变量,定义整型变量 lenc,x,num 分别表示两个高精度数相加后的数的位数长度,进位和进位的次数,对 lenc,x,num 赋初始值为 0;
char a1[1001]= {},b1[1001]= {};
int a[1001]= {},b[1001]= {},c[1001]= {},lena,lenb,i;
int lenc = 0,x = 0,num = 0;
第二步:输入两个高精度数,并分别求出两个高精度数的长度;
cin>>a1>>b1;
lena = strlen(a1);
lenb = strlen(b1);
第三步:使用 for 循环遍历,分别将存储在字符数组里的被加数和加数字符串转换为数字, 并倒序储存到整型数组里;
for(i = 0; i <= lena-1; i++) {
a[lena-i-1] = a1[i] - 48;
}
for(i = 0; i <= lenb -1; i++) {
b[lenb-i-1] = b1[i] - 48;
}
第四步:使用 while 循环语句对各个数位上的数求和,满足相加得到的位数小于 a 的长度或者 b 的长度时,执行循环语句,每次循环的过程中将 a 和 b 对应位的数相加并加上进位 x 的值,得到对应数位的数存储在 c 数组中,因为得到的数可能超过 10,因此计算完后需要进行进位 x 值的更新。使用 if 语句判断 x 的值为 1 时,num 加 1。然后用该数对 10 取余得到该位上的数;
while(lenc<lena||lenc<lenb) {
c[lenc]=a[lenc]+b[lenc]+x;
x = c[lenc]/10;
if(x==1){
num++;
}
c[lenc] = c[lenc]%10; lenc++;
}
第五步:输出 num 的值;
cout << num;
完整代码:
#include <iostream>
#include <cstring>
using namespace std;
int main (){
char a1[1001]={},b1[1001]={};
int a[1001]={},b[1001]={}, c[1001]= {};
int lena,lenb,i,len = 0,x = 0,num = 0;
cin >> a1 >> b1;
lena = strlen(a1);
lenb = strlen(b1);
for(i = 0; i <= lena-1; i++) {
a[lena-i-1] = a1[i] - 48;
}
for(i = 0; i <= lenb -1; i++) {
b[lenb-i-1] = b1[i] - 48;
}
while(len<lena || len<lenb){
a[len]=a[len]+b[len]+x;
x=a[len]/10;
if(x==1)
num++;
a[len] = a[len]%10;
len++;
}
cout << num;
return 0;
}