标签:加法 font get hide oid 直接 返回 alt +=
之前总是嫌打高精烦,这次干脆打了个模板出来。
这篇主要是给新手讲的,如果你只是要co模板,点下面co即可。(不懂可以往下看)
#include<cstdio> using namespace std; const int wei=100000; int a[100][wei],bz[100],ad[100]; void read(int i) { char ch=getchar(); bz[i]=1,ad[i]=0; int b[wei]; while (ch<‘0‘ || ch>‘9‘) { if (ch==‘-‘) bz[i]=-1; ch=getchar(); } while (ch>=‘0‘ && ch<=‘9‘) { b[++ad[i]]=ch-‘0‘;ch=getchar();} for (int j=1;j<=ad[i];++j) a[i][ad[i]-j+1]=b[j]; } void add(int i,int j,int k) { if (bz[i]==bz[j]) { if (ad[i]>ad[j]) ad[k]=ad[i]; else ad[k]=ad[j]; for (int l=1;l<=ad[k];++l) { a[k][l]+=a[i][l]+a[j][l]; a[k][l+1]+=a[k][l]/10; a[k][l]%=10; } if (a[k][ad[k]+1]>0) ++ad[k]; bz[k]=bz[i]; return; } else { int bz1=0,bz2=0; if (ad[i]>ad[j]) { bz1=i,bz2=j,ad[k]=ad[i]; } else { ad[k]=ad[j];if (ad[i]<ad[j]) bz1=j,bz2=i;} for (int l=ad[k];l>0;--l) if (bz1>0) break; else { if (a[i][l]>a[j][l]) { bz1=i,bz2=j;break; } else { if (a[i][l]<a[j][l]) { bz1=j,bz2=i;break; } } } if (bz1==0) { ad[k]=1;a[k][1]=0;return; } for (int l=1;l<=ad[k];++l) { if (a[k][l]+a[bz1][l]-a[bz2][l]<0) a[k][l+1]-=1,a[k][l]+=10; a[k][l]+=a[bz1][l]-a[bz2][l]; a[k][l+1]+=a[k][l]/10; a[k][l]%=10; } if (a[k][ad[k]]<=0) ad[k]--; bz[k]=bz[bz1]; return; } } void sub(int i,int j,int k) { bz[j]*=-1; add(i,j,k); bz[j]*=-1; return; } int main() { read(1); read(2); add(1,2,3); read(4); sub(3,4,5); if (bz[5]==-1) printf("-"); for (int i=ad[5];i>0;--i) printf("%d",a[5][i]); }
基于个人码风不同,这里主要采用较为方便的形式,如有觉得很乱还请见谅。
加减法主要采用模拟手动运算解决,如果你打了加法,减法则可以直接转换为加法(具体看下面)
下面代码中附有具体操作:
#include<cstdio>
using namespace std;
const int wei=100000; //数的位数限制,目前为10100000。
int a[100][wei],bz[100],ad[100]; //a记录数,bz记录数的正负,ad记录数的位数。
void read(int i) //读入高精度数,i为数的编号。
{
char ch=getchar();
bz[i]=1,ad[i]=0;
int b[wei];
while (ch<‘0‘ || ch>‘9‘) { if (ch==‘-‘) bz[i]=-1; ch=getchar(); }
while (ch>=‘0‘ && ch<=‘9‘) { b[++ad[i]]=ch-‘0‘;ch=getchar();}
for (int j=1;j<=ad[i];++j) a[i][ad[i]-j+1]=b[j];
}
void add(int i,int j,int k) //此为高精度加法,将编号为i的数与编号为j的数相加,存入编号k,(i,j,k可以相同)
{
if (bz[i]==bz[j]) //如果正负相等,直接相加减即可。
{
if (ad[i]>ad[j]) ad[k]=ad[i]; else ad[k]=ad[j]; //判断新数的位数。
for (int l=1;l<=ad[k];++l) //对每位进行加减
{
a[k][l]+=a[i][l]+a[j][l];
a[k][l+1]+=a[k][l]/10;
a[k][l]%=10; //进行进位操作
}
if (a[k][ad[k]+1]>0) ++ad[k]; //判断相加后有无新产生数
bz[k]=bz[i]; //正负取原符号
return;
} else
{ //对两个数符号不同进行处理
int bz1=0,bz2=0;
if (ad[i]>ad[j]) { bz1=i,bz2=j,ad[k]=ad[i]; }
else { ad[k]=ad[j];if (ad[i]<ad[j]) bz1=j,bz2=i;} //判断新数位数
for (int l=ad[k];l>0;--l) //找出两数中较大和较小数,bz1为较大数,bz2为较小数
if (bz1>0) break; else
{
if (a[i][l]>a[j][l]) { bz1=i,bz2=j;break; }
else { if (a[i][l]<a[j][l]) { bz1=j,bz2=i;break; } }
}
if (bz1==0) { ad[k]=1;a[k][1]=0;return; } //如果两数相等,返回0
for (int l=1;l<=ad[k];++l) //用较大数减较小数
{
if (a[k][l]+a[bz1][l]-a[bz2][l]<0) a[k][l+1]-=1,a[k][l]+=10; //进行借位操作
a[k][l]+=a[bz1][l]-a[bz2][l];
a[k][l+1]+=a[k][l]/10;
a[k][l]%=10;
}
if (a[k][ad[k]]<=0) ad[k]--; //判断是否减掉一位
bz[k]=bz[bz1]; //取较大数符号
return;
}
}
void sub(int i,int j,int k) //高精度减法,含义同加法。
{ //根据减法法则,减去一个数相当于加上一个数的相反数,则将减数取反,再加即可。
bz[j]*=-1;
add(i,j,k);
bz[j]*=-1;
return;
}
int main() //此为实验
{
read(1); //读入编号为一的数
read(2); //读入编号为二的数
add(1,2,3); //将一和二相加
read(4); //读入编号为四的数
sub(3,4,5); //将三减四
if (bz[5]==-1) printf("-"); //输出带符号
for (int i=ad[5];i>0;--i) //输出结果
printf("%d",a[5][i]);
}
加法和减法就这样即可,有意见欢迎在评论区提出。
标签:加法 font get hide oid 直接 返回 alt +=
原文地址:https://www.cnblogs.com/T-Y-Y-H/p/13504094.html