高精度(加法+减法+除法+乘法)合集

 由于c++/c语言特性,当数很大时,就要考虑精度问题,python和java则不用,因此c++学会精度运算很重要的,这里作个总结

1.高精度加法

给定两个正整数(不含前导 0),计算它们的和。

输入格式

共两行,每行包含一个整数。

输出格式

共一行,包含所求的和。

数据范围

1≤整数长度≤100000

输入样例:

12
23

输出样例:

35

 思路:,这么大的数字用int,long long之类的肯定不好处理,但如果把一个很大数字的每一位存进一个数组里,那就很好的解决这个问题,这里用vector存储避免数组开太大,多的用不到。

存入一个数组之后两个数组就是每一位相加,大于10就进位,和小学时学的数学相加一样,不废话直接出代码

代码实现:

#include<iostream>
#include<vector>
using namespace std;

//计算C
vector<int> add(vector<int> &A,vector<int> &B)//这里加&就不用再拷贝了,加快效率
{
    vector<int> C;
    
    int t=0;
    for(int i=0;i<A.size()||i<B.size();i++)
    {
        if(i<A.size()) t+=A[i];
        if(i<B.size()) t+=B[i];
        C.push_back(t%10);//c的值就是进位的个位数
        t/=10;把t的个位数去掉只剩下十位数,即只剩下这个位置的进位
    }
    if(t) C.push_back(1);//如果t==1,表示还有一个进位,要补上
    return C;
}

int main()
{
    string a,b;//由于数字可能很长,用string存储
    cin>>a>>b;
    vector<int> A,B;
    
    //A和B倒着放进int数组,因为有进位,倒着放容易处理
    for(int i=a.size()-1;i>=0;i--) A.push_back(a[i]-'0');//倒序存储
    for(int i=b.size()-1;i>=0;i--) B.push_back(b[i]-'0');
    
    auto C=add(A,B);
    for(int i=C.size()-1;i>=0;i--) cout<<C[i];
    cout<<endl;
    return 0;
}

 2.高精度减法

给定两个正整数(不含前导 0),计算它们的差,计算结果可能为负数。

输入格式

共两行,每行包含一个整数。

输出格式

共一行,包含所求的差。

数据范围

1≤整数长度≤105

输入样例:

32
11

输出样例:

21

 思路:和高精度加法一样,这里一样用了我们小学学的减法的公式,每一位与每一位对应相减,不够就要往高位借位,如果被减的数比减它的数更大,此时可以变成-(被减的数-原本该减它的数),比如我要求4-9,此时需要输出-5,可以看成-(9-4),保证里面大数减去小数,我们的代码就更容易实现

代码实现:

#include<iostream>
#include<vector>
using namespace std;
//判断A和B的长度哪个大
bool cmp(vector<int> &A,vector<int> &B)
{
    if(A.size()!=B.size()) return A.size()>B.size();//假如大于号为真,则返回前面的值,否则返回后面的值
    
    for(int i=A.size()-1;i>=0;i--)
        if(A[i]!=B[i]) return A[i]>B[i];
    return true;
}
vector<int> sub(vector<int> &A,vector<int> &B)//这里通过前面的判断,进来的A长度必然>=B的长度
{
    vector<int> C;
    int t=0;
    for(int i=0;i<A.size();i++)
    {
        t=A[i]-t;
        if(i<B.size()) t-=B[i];
        C.push_back((t+10)%10);
        if(t<0) t=1;
        else t=0;
    }
    while(C.size()>1&&C.back()==0) C.pop_back();//这步操作是为了去除前面的0,比如600-599=001,前面的两个0要去掉
    return C;
}
int main()
{
    string a,b;
    cin>>a>>b;
    
    vector<int> A,B;
    for(int i=a.size()-1;i>=0;i--) A.push_back(a[i]-'0');
    for(int i=b.size()-1;i>=0;i--) B.push_back(b[i]-'0');

    vector<int> C;
    if(cmp(A,B)) C=sub(A,B);
    else C=sub(B,A),cout<<"-";
    for(int i=C.size()-1;i>=0;i--) cout<<C[i];
    cout<<endl;
    return 0;
}

3.高精度乘法

给定两个非负整数(不含前导 0) A 和 B,请你计算 A×B 的值。

输入格式

共两行,第一行包含整数 A,第二行包含整数 B。

输出格式

共一行,包含 A×B 的值。

数据范围

1≤A的长度≤100000,
0≤B≤10000

输入样例:

2
3

输出样例:

6

 思路:仍然是用小学我们学数学的乘法思路进行计算,由于这里是一个很大的数和一个小数相乘,因此就是把大数存入数组,从个位开始每个元素乘以 该小数b,留下模10后的数,进除以10后的数,这里直接放代码更好理解。(两个大数相乘稍微改一下思路就行,这题是大数乘小数)

代码实现:

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
vector<int> xiaochou(vector<int>&A,int b)
{
    vector<int> C;
    int t=0;//进位
    for(int i=0;i<A.size()||t;i++)//这里注意假如t还存在也要继续存
    {
        if(i<A.size()) t+=A[i]*b;
        C.push_back(t%10);//把每个位置相乘后的数模10存进C中
        t/=10;//除10,进位
    }
    
    while(C.size()>1&&C.back()==0) C.pop_back();//假如相乘为0,比如26乘0的话就会等于00,
                                                //应当去除掉多余的0只保留一个
    return C;
}
int main()
{
    string a;
    int b;
    cin>>a>>b;
    
    vector<int> A;
    for(int i=a.size()-1;i>=0;i--) A.push_back(a[i]-'0');
    auto C=xiaochou(A,b);
    for(int i=C.size()-1;i>=0;i--) printf("%d",C[i]);
    cout<<endl;
    return 0;
}

 4.高精度除法

给定两个非负整数(不含前导 0) A,B,请你计算 A/B 的商和余数。

输入格式

共两行,第一行包含整数 A,第二行包含整数 B。

输出格式

共两行,第一行输出所求的商,第二行输出所求余数。

数据范围

1≤A的长度≤100000,
1≤B≤10000,
B 一定不为 0

输入样例:

7
2

输出样例:

3
1

 思路:同样是小学我们学除法的思路,如图所示

 代码实现也不难,这里直接给出来了

代码实现:

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
vector<int> xiaochou(vector<int>&A,int b,int& r)//这里要注意r要传入指针,r改变主函数的r也改变
{
    vector<int> C;

    for(int i=A.size()-1;i>=0;i--)
    {
        r=r*10+A[i];//(前一位的余数*10+当前该数)即是此时应当被b除的数
        C.push_back(r/b);
        r%=b;
    }

    reverse(C.begin(),C.end());//这里翻转是为了更好的出去无用的前导0
    while(C.size()>1&&C.back()==0) C.pop_back();
    return C;
}
int main()
{
    string a;
    int b;
    cin>>a>>b;
    
    vector<int> A;
    for(int i=a.size()-1;i>=0;i--) A.push_back(a[i]-'0');
    int r=0;//存储余数
    auto C=xiaochou(A,b,r);
    for(int i=C.size()-1;i>=0;i--) printf("%d",C[i]);
    printf("\n%d\n",r);
    return 0;
}

注意:这里可能有人会疑惑为什么还要倒序存入A中,这里正常来讲由于除法的特性其实不倒叙更好,但是由于一般的题目中不可能只考一个除法(由前面知道加减乘都是倒序存储),因此我们统一给他倒序存入,方便其他操作(如加减乘)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值