高精度
用字符串存储,模拟四则运算
为了方便个位对齐,把字符串倒着转化到另一个int数组中,高位补零(初始化为0),数组中的元素代表原数中的某一位,输出需要倒序输出
高精度加法
- 结果数最大长度max(la,lb)+1
- 先进位再保留余数
int a[maxNum],b[maxNum],c[maxNum]; //c是结果数组
string s1,s2;
int la,lb,lc;
void add(){
cin>>s1>>s2;
la=s1.length();
lb=s2.length();
lc=max(la,lb)+1; //最大结果长度
//倒序存
for(int i=0;i<la;i++){
a[i]=s1[la-1-i]-'0';
}
for(int i=0;i<lb;i++){
b[i]=s2[lb-1-i]-'0';
}
//模拟加法
for(int i=0;i<max(la,lb);i++){
c[i]+=a[i]+b[i];
c[i+1]+=c[i]/10;
c[i]=c[i]%10;
}
//去掉前导零
lc--; //把lc转化成最高位下标
while(c[lc]==0&&lc>0)lc--;
//输出
for(int i=lc;i>=0;i--){
cout<<c[i];
}
cout<<endl;
}
高精度减法
- 结果数最大长度max(la,lb)
- 先比较两个数,保证大减小
- 先借位,再相减(或先相减,再借位),最高位不会借位
int a[maxNum],b[maxNum],c[maxNum]; //c是结果数组
string s1,s2;
int la,lb,lc;
void sub(){
cin>>s1>>s2;
lc=max(la,lb);
if(la<lb||(la==lb&&s1<s2)){
cout<<'-'; //先输出负号
swap(s1,s2);
}
la=s1.length();
lb=s2.length();
for(int i=0;i<la;i++){
a[i]=s1[la-1-i]-'0';
}
for(int i=0;i<lb;i++){
b[i]=s2[lb-1-i]-'0';
}
for(int i=0;i<lc;i++){
if(a[i]<b[i]){ //不够就借位
a[i]+=10;
a[i+1]--;
}
c[i]=a[i]-b[i];
/* 先相减再借位,不会改动a数组
c[i]+=a[i]-b[i];
if(c[i]<0){
c[i]+=10;
c[i+1]--;
}
*/
}
//去掉前导零
lc--; //把lc转化成最高位下标
while(c[lc]==0&&lc>0)lc--;
//输出
for(int i=lc;i>=0;i--){
cout<<c[i];
}
cout<<endl;
}
高精度乘法
- 结果数最大长度为la+lb
- 两层循环,一层a的每位,一层b的每位
- 错位相乘c[i+j]+=a[i]+b[j]
- 最后再处理进位
int a[maxNum],b[maxNum],c[2*maxNum]; //c是结果数组
string s1,s2;
int la,lb,lc;
void multi(){
cin>>s1>>s2;
la=s1.length();
lb=s2.length();
lc=la+lb;
for(int i=0;i<la;i++){
a[i]=s1[la-1-i]-'0';
}
for(int i=0;i<lb;i++){
b[i]=s2[lb-1-i]-'0';
}
for(int i=0;i<la;i++){
for(int j=0;j<lb;j++){
c[i+j]+=a[i]*b[j];
}
}
for(int i=0;i<lc;i++){
c[i+1]+=c[i]/10;
c[i]=c[i]%10;
}
lc--;
while(c[lc]==0&&lc>0)lc--;
for(int i=lc;i>=0;i--){
cout<<c[i];
}
cout<<endl;
}
高精度除法
结果向下取整
- 较小的数除以较大的数结果是0
- 结果数长度为la-lb+1
- 从数组下标1开始存,下标0存数的长度
- 用temp数组存b数,让b的最低位与c的要计算的位对齐,低位补零
- 减法模拟除法
- 若除数或被除数有前导零需要先去掉前导零
int a[maxNum],b[maxNum],c[maxNum];
int temp[maxNum]; //临时数组
//int la,lb,lc;
bool cmp(int *x,int *y){ //x大于等于y返回true
if(x[0]>y[0])return true;
else if(x[0]<y[0])return false;
else {
for(int i=x[0];i>=1;i--){
if(x[i]>y[i])return true;
else if(x[i]<y[i])return false;
}
return true;
}
}
void sub(int *x,int *y){
for(int i=1;i<=x[0];i++){
if(x[i]<y[i]){ //借位
x[i]+=10;
x[i+1]--;
}
x[i]-=y[i];
}
//去掉前导零得到结果位数
int i=x[0];
while(x[i]==0&&i>1)i--;
x[0]=i;
}
void divi(){
cin>>s1>>s2;
a[0]=s1.length;
b[0]=s2.length;
for(int i=1;i<=a[0];i++){
a[i]=s1[a[0]-i]-'0';
}
for(int i=1;i<=b[0];i++){
b[i]=s2[b[0]-i]-'0';
}
if(cmp(a,b)==false){ //小数除大数直接输出0
cout<<0<<endl;
return;
}
c[0]=a[0]-b[0]+1;
for(int i=c[0];i>=1;i--){ //从高位开始计算商的每一位
memset(temp,0,sizeof(temp));
//把b存在temp的高位
for(int j=1;j<=b[0];j++){
temp[i+j-1]=b[j];
}
temp[0]=i+b[0]-1;
while(cmp(a,temp)){
sub(a,t);
c[i]++;
}
}
int i=c[0];
while(c[i]==0&&i>1)i--;
c[0]=i;
for(int j=c[0];j>=1;j--){
cout<<c[j];
}
cout<<endl;
}

浙公网安备 33010602011771号