码迷,mamicode.com
首页 > 编程语言 > 详细

高精度加减-C++模板-实现-超详细

时间:2020-08-17 17:18:02      阅读:63      评论:0      收藏:0      [点我收藏+]

标签:加法   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]);
}

加法和减法就这样即可,有意见欢迎在评论区提出。

高精度加减-C++模板-实现-超详细

标签:加法   font   get   hide   oid   直接   返回   alt   +=   

原文地址:https://www.cnblogs.com/T-Y-Y-H/p/13504094.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!