c++高精度(极简版)--加减乘

c++高精度(极简版)–加减乘

在各种赛事中,虽然可以用python来解决高精度的问题,但是为了提高自己的代码能力,于是就写了一篇文章,来记录一下自己对c++高精度的处理。(整理成模版,以便背诵)

(本文都假设是两个正整数之间的运算)

姑且先写加法减法和乘法的高精度,因为除法比较麻烦,后续会单独出一篇文章写高精度除法

模版


加法

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
string add(string s1,string s2)
{
    int x[maxn]={},y[maxn]={},temp=0;
    int l1=s1.size(),l2=s2.size();
    string ret="";
    for(int i=1;i<=l1;i++) x[i]=s1[l1-i]-'0';
    for(int i=1;i<=l2;i++) y[i]=s2[l2-i]-'0';
    for(int i=1;i<=max(l1,l2);i++)
    {
        ret=to_string((temp+x[i]+y[i])%10)+ret;
        temp=(x[i]+y[i])/10;
    }
    if(temp!=0) ret=to_string(temp)+ret;
    return ret;
}
int main()
{
    string s1,s2;
    cin>>s1>>s2;
    cout<<add(s1,s2)<<endl;
    return 0;
}

减法

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
string sub(string s1,string s2)
{
    int x[maxn]={},y[maxn]={};
    int l1=s1.size(),l2=s2.size();
    int flag=1,k=0,temp=0;
    string ret="";
    if(l1<l2) swap(s1,s2),flag=0;
    else if(l1==l2) 
    {
        int now=0;
        while(s1[now]==s2[now]) now++;
        if(s1[now]<s2[now] && now<l1) swap(s1,s2),flag=0;
        
    }

    for(int i=1;i<=l1;i++) x[i]=s1[l1-i]-'0';
    for(int i=1;i<=l2;i++) y[i]=s2[l2-i]-'0';
    for(int i=1;i<=l1;i++)
    {
        k=x[i]-y[i]+temp,temp=0;
        while(k<0) k+=10,temp--;
        ret=to_string(k)+ret;
    }
    
    int now=0;
    while(ret[now]=='0') now++;
    ret=ret.substr(now);
    if(!flag) ret='-'+ret;
    if(ret=="") ret="0";
    return ret;
}
int main()
{
    string s1,s2;
    cin>>s1>>s2;
    cout<<sub(s1,s2)<<endl;
    return 0;
}

乘法

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
string multi(string s1,string s2)
{
    int x[maxn]={},y[maxn]={},ret[maxn]={};
    int l1=s1.size(),l2=s2.size();
    string ret_string ="";
    for(int i=1;i<=l1;i++) x[i]=s1[l1-i]-'0';
    for(int i=1;i<=l2;i++) y[i]=s2[l2-i]-'0';
    for(int i=1;i<=l1;i++)
    {
        for(int j=1;j<=l2;j++)
        {
            ret[i+j]+=(ret[i+j-1]+x[i]*y[j])/10;
            ret[i+j-1]=(ret[i+j-1]+x[i]*y[j])%10;
        }
    }
    int begin=l1+l2;
    while(ret[begin]==0) begin--;
    for(int i=begin;i>=1;i--) ret_string+=(char)(ret[i]+'0');
    return ret_string;
}
int main()
{
    string s1,s2;
    cin>>s1>>s2;
    cout<<multi(s1,s2)<<endl;
    return 0;
}

例题

高精度求累加和

使用求和公式求1到N的累加和大家都会,但是如果把N值变大呢,比如100位的整数,那该怎么求?

输入格式:

输入在一行中给出1个位数不超过100位的整数N。

输出格式:

对每一组输入,在一行中输出1+2+3+……+N的值。

输入样例:

在这里给出一组输入。例如:

10
输出样例:

在这里给出相应的输出。例如:

55

思路

这道题就是综合运用加法和乘法的高精度,然后在把得到的结果除以2(有一点除法高精度的思想),就可以得到答案

代码实现

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
string add(string s1,string s2)
{
    int x[maxn]={},y[maxn]={},temp=0;
    int l1=s1.size(),l2=s2.size();
    string ret="";
    for(int i=1;i<=l1;i++) x[i]=s1[l1-i]-'0';
    for(int i=1;i<=l2;i++) y[i]=s2[l2-i]-'0';
    for(int i=1;i<=max(l1,l2);i++)
    {
        ret=to_string((temp+x[i]+y[i])%10)+ret;
        temp=(x[i]+y[i])/10;
    }
    if(temp!=0) ret=to_string(temp)+ret;
    return ret;
}

string multi(string s1,string s2)
{
    int x[maxn]={},y[maxn]={},ret[maxn]={};
    int l1=s1.size(),l2=s2.size();
    string ret_string ="";
    for(int i=1;i<=l1;i++) x[i]=s1[l1-i]-'0';
    for(int i=1;i<=l2;i++) y[i]=s2[l2-i]-'0';
    for(int i=1;i<=l1;i++)
    {
        for(int j=1;j<=l2;j++)
        {
            ret[i+j]+=(ret[i+j-1]+x[i]*y[j])/10;
            ret[i+j-1]=(ret[i+j-1]+x[i]*y[j])%10;
        }
    }
    int begin=l1+l2;
    while(ret[begin]==0) begin--;
    for(int i=begin;i>=1;i--) ret_string+=(char)(ret[i]+'0');
    return ret_string;
}
string div(string s)
{
    string R="";
    int temp=0;
    if(((int)s[0]-48)/2)
    {
        R=to_string(((int)s[0]-48)/2);
        
    }
    temp=((int)s[0]-48)%2*10;
    for(int i=1;i<=s.size()-1;i++)
    {
        R=R+to_string((((int)s[i]-48)+temp)/2);
        temp=(((int)s[i]-48)+temp)%2*10;
    }
    return R;
}
int main()
{
    string s1;
    cin>>s1;
    cout<<div(multi(add(s1,"1"),s1))<<endl;
    return 0;
}

小结

c++加法,减法和乘法的高精度的实现都是通过基本的竖式计算,只需要注意进位即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值