【总结】高精度运算
高精度运算
——它没大有什么用处。
一般来说考试并不会有特别毒瘤的出题人去专门给你卡高精
但写一些高精的题可以提升一下代(打)码(发)能(时)力(间)(滑稽
这里主要介绍高精度运算的三种比较简单的类型:
高精度加法,高精度减法,高精度乘法
高精度加法
既然c++语言解决不了数位过大的加减运算问题,那么我们可以想到小学做加法时的列竖式计算,手动模拟一个列竖式的过程来进行较多数位的加法运算问题qwq
大概流程(趴:
1.读入两个字符串,将字符串的每一位转为int类型分别存在两个数组中
2.对于每一位进行加法运算,运算结果存在另一个数组中
3.特殊处理加法的进位,以及特殊处理最高位
4.输出最后结果
Code
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <math.h>
using namespace std;
char aa[2000];
char bb[2000];
int a[2000],b[200],c[200];
int lena,lenb;
void jf(){
int len = max(lena,lenb); cout << len <<endl;
for(int i = 0;i < len;i++){
c[i] += a[i] + b[i];
if(c[i] >= 10){
c[i+1] += 1;
c[i]%=10;
}
}
if(c[len] == 1)len++;
while(c[len-1] == 0){len--;}
for(int i = len-1;i >= 0 ;i --)
cout<<c[i];
return;
}
int main(){
scanf("%s",aa);
scanf("%s",bb);
lena = strlen(aa);lenb = strlen(bb);
for(int i = 0;i < lena;i ++)
a[i] = aa[lena-i-1] - '0';
for(int i = 0;i < lenb;i++)
b[i] = bb[lenb-i-1] - '0';
//for(int i = 0;i < lena; i++)cout<<a[i];
jf();
}
高精度减法
减法同加法是大致类似的,既然我们可以在解决加法问题时利用竖式解决,那么同理减法也可以做到,具体实现也就是依靠竖式减法来完成
大致流程和加法类似,需要将进位的过程转化为借位。
Code
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
char aa[1000],bb[1000];
int a[10000],b[10000],c[10000];
int lena,lenb;
void _solve(){
int len = max(lena,lenb);
for(int i = 0;i < len;i++)
c[i] = a[i] - b[i];
for(int i = 0;i < len;i++)
if(c[i] < 0){
c[i+1] -= 1;
c[i] += 10;
}
while(c[len-1] == 0){
len--;
}
for(int i = len-1;i >=0;i--){
cout << c[i];
}
}
int main(){
scanf("%s",aa);
scanf("%s",bb);
lena = strlen(aa),lenb = strlen(bb);
for(int i = 0;i < lena;i++)
a[i] = aa[lena-i-1]-'0';
for(int i = 0;i < lenb;i++)
b[i] = bb[lenb-i-1]-'0';
_solve();
}
高精度乘法
ummmm……(肥宅叹气
高精度乘法又双叒叕是根据小学的竖式计算来完成,我们可以用第二个乘数的每一位依次去乘以第一个数的每一位,将所得的乘积对应累加在一个数组对应的数位中,最后再去考虑进位(乘法的进位有可能不是进1位了qwq)以及最高位0的处理。
观察可以发现,第一个数从最低位开始数第i位ai,乘以第二个数从最低位开始数的第j位bj相乘的积可以存在下标位i+j的数组c中。
Code
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
using namespace std;
char aa[1000],bb[1000];
int a[1000],b[1000],c[10000];
int lena,lenb;
void _Solve(){
for(int i = 0;i < lenb;i++)
for(int j = 0;j < lena;j ++){
c[i+j] += b[i]*a[j];
}
int k = 0;
while(k <= lena + lenb){
//cout<<k<<" "<<c[k]<<endl;
if(c[k] >= 10){
c[k+1] += (c[k]/10);
c[k] %= 10;
//cout<<c[k]/10<<endl;
}
k++;
}
while(c[k-1] == 0){
k--;
}
for(int i = k-1;i >= 0;i --){
cout << c[i];
}
return;
}
int main(){
scanf("%s",aa);
scanf("%s",bb);
lena = strlen(aa);
lenb = strlen(bb);
for(int i = 0;i < lena;i ++)
a[i] = aa[lena-i-1] - '0';
for(int i = 0;i < lenb;i ++)
b[i] = bb[lenb-i-1] - '0';
_Solve();
}
嗯 没了,别看了hhh。
啊啊不对,还有(2020.1.17)补充
!压位
一个int只存储0到9的数字位,使得我们的程序空间和时间效率都不高
int的最大范围可以达到2147483647,所以一个int存储8位是没问题的
在读入和输出的时候要注意,除了最高位之外要补0