3.C++秒懂高精度数

高精度数加法运算的进位问题

知识目标

  • 学习高精度数加法运算的进位。高精度数的加法运算——进阶高精度数的加法运算

【问题描述】

输入两个高精度数,输出这两个数的和(两个高精度数位数不一定相同且可能存在进位)。

【样例输入 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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值