C++高精度问题

这篇具有很好参考价值的文章主要介绍了C++高精度问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

高精度前言

C++中int不能超过2^31-1,最长的long long也不能超过2^63-1,所以我们在题目中如果碰到了很长很长的数,并且需要进行大数运算时,就需要高精度存储。

高精度总体思路

由于int和long long的限制,我们要想存放很长的数就需要利用数组存储,C++中可以利用STL中的vector容器存储

读取: 由于数据很大,用int存放不下,一般利用字符串读取

数据存放:用vector倒序存储,即将小位放到前面,将大位放到后面,这样方便数据处理

高精度算法

高精度加法

示例题目:

C++高精度问题,c++,开发语言,visual studio,c语言,算法

C++高精度问题,c++,开发语言,visual studio,c语言,算法

我们一般习惯是加法从个位数开始运算, t表示进位,初始t为0。先将个位数相加,图中为6+5=11

在加法中11%10 = 1为个位,11/10=1为进位,即t = 1,所以十位数相加为2+4+1=7,如此往复。根据此思路即可写出代码

//高精度加法
#include<iostream>
using namespace std;
#include<vector>

vector<int> add(vector<int> A,vector<int> B)
{
    //进位t初始为0
    int t = 0;
    vector<int> C;
    //i到任意一方结尾停止
    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];
        //相加后如果大于10要取余作为个位,如果小于10不影响
        C.push_back(t%10);
        //算进位
        t = t/10;
    }
    //最后一次计算 如果t为1 要在最高位补1
    if(t) C.push_back(t);
    return C;
}

int main()
{
    vector<int> A,B;
    //利用字符串读取
    string a,b;
    cin>>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');
    //auto为自动判断类型,会自动判断函数的返回类型
    auto C = add(A,B);
    for(int i = C.size()-1;i>=0;i--) cout<<C[i];
}

其中a[i]-'0'是将字符类型的数字转换为整型类型的数字

需要注意的是这段代码

if(t) C.push_back(t);

这为了解决50+50 = 100类似的情况,最后一次计算后如果t=1,则需要在最高位补1。

高精度减法

示例题目: 

C++高精度问题,c++,开发语言,visual studio,c语言,算法

减法计算思路与加法相似

C++高精度问题,c++,开发语言,visual studio,c语言,算法

此时t表示的是借位,总体计算公式为 a[i]-b[i]-借位。

借位的计算

C++高精度问题,c++,开发语言,visual studio,c语言,算法

如果这次的A[i]-B[i] >= 0则下次的借位为0,反之下次计算的借位为1。

解决了计算的问题,减法还有负数的问题,如果小数减去大数要为负数,所以我们需要自己写一个判断两数大小的函数

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;
}

先比较两数的位数,再依次比较两数的每一位,到最后还未得出结果,则返回true表示两数相等

在输出时分类讨论,负数先输出负号在输出数据即可

完整代码

//高精度减法模板
#include<iostream>
using namespace std;
#include<vector>
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)
{
    vector<int> C;
    for(int i=0,t=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;
    }
    //去除前导0
    while(C.size()>1 && C.back() ==0  ) C.pop_back();
    return C;
}

int main()
{
    string a,b;
    vector<int> A,B;
    cin>>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');
    //正数
    if(cmp(A,B))
    {
        auto C = sub(A,B);
        for(int i = C.size()-1;i>=0;i--) cout<<C[i];
    }
    //负数
    else
    {
        auto C = sub(B,A);
        cout<<"-";
        for(int i = C.size()-1;i>=0;i--) cout<<C[i];
    }


    return 0;
}

在题目中可能会出现需要去除前导0的情况

C++高精度问题,c++,开发语言,visual studio,c语言,算法

例如输出023,这个0没有实际意义,需要去除,被称为前导0

利用下面这段代码即可去除前导0

while(C.size()>1 && C.back() ==0  ) C.pop_back();

高精度乘法

示例题目:

C++高精度问题,c++,开发语言,visual studio,c语言,算法

高精度乘法一般只考虑大数乘以小数

C++高精度问题,c++,开发语言,visual studio,c语言,算法

与加法十分类似,所以具体思路参考加法,需要注意的是,乘法也需要去前导0.

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

vector<int> mul(vector<int> A,int b)
{
    vector<int> C;
    int t = 0;
    for(int i = 0;i<A.size();i++) 
    {
        if(i<A.size()) t += A[i]*b;
        C.push_back(t%10);
        t = t/10;
    }
    while(C.size() >1 && C.back() == 0) C.pop_back();
    return C;
}

int main()
{
    string a;
    int b;
    vector<int> A;
    cin>>a>>b;
    for(int i = a.size()-1;i>=0;i--) A.push_back(a[i]-'0');
    auto C = mul(A,b);
    for(int i = C.size()-1;i>=0;i--) cout<<C[i];
    return 0;
}

高精度除法

实例题目

C++高精度问题,c++,开发语言,visual studio,c语言,算法

高精度除法需要注意的是余数,并且与加减乘法不同的是,除法是从高位开始计算的,而加减乘法是从低位开始计算的,需要加以区别

C++高精度问题,c++,开发语言,visual studio,c语言,算法

模拟除法过程我们可以发现,每次的被除数是上次计算得到的余数r*10加上a[i],在图中为

1*10+5=15,我们将r/b入数组即可。

完整代码

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

vector<int> div(vector<int>& A,int b,int& r)//r传入r的地址,便于直接对余数r进行修改
{
    r = 0;
    vector<int> C;
    for(int i = A.size()-1;i>=0;i--)//对A从最高位开始处理
    {
        r = r*10+A[i];//对A从最高位开始处理
        C.push_back(r/b);//将上次的余数*10在加上当前位的数字,便是该位需要除的被除数
        r = r%b;//余数
    }
    //由于在除法运算中,高位到低位运算,因此C的前导零都在vector的前面而不是尾部,vector只有删除最后一个数字pop_back是常数复杂度,而对于删除第一位没有相应的库函数可以使用,而且删除第一位,其余位也要前移,
    //因此我们将C翻转,这样0就位于数组尾部,可以使用pop函数删除前导0
    reverse(C.begin(),C.end());
    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;
    auto C = div(A,b,r);
    for(int i = C.size()-1;i>=0;i--) cout<<C[i];
    cout<<endl<<r<<endl;
}

高精度除法同样需要去除前导0,不过不同的是,由于在除法运算中,高位到低位运算,因此C的前导零都在vector的前面而不是尾部,vector只有删除最后一个数字pop_back是常数复杂度,而对于删除第一位没有相应的库函数可以使用,而且删除第一位,其余位也要前移,因此我们可以利用reverse()函数将C翻转,这样0就位于数组尾部,可以使用pop函数删除前导0

此篇为学习之余的总结,作为笔记使用,如果有错误还请指正,谢谢!文章来源地址https://www.toymoban.com/news/detail-820726.html

到了这里,关于C++高精度问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 高精度减法(C语言实现)

    众所周知,整数在C和C++中以 int , long , long long 三种不同大小的数据存储,数据大小最大可达 2^64 ,但是在实际使用中,我们仍不可避免的会遇到爆 long long 的超大数运算,这个时候,就需要我们使用高精度算法,来实现巨大数的运算。 高精度的本质是将数字以字符串的形

    2024年02月05日
    浏览(43)
  • 高精度除法【c++实现】超详细讲解

    高精度算法分为两种,高精除以低精和高精除以高精。不要看都是除法,就认为原理类似,其实是有很大差距的。让我们一起来学习吧! 有句话说在前面,如果除数等于0,就不要算了,不成立。( 如果你忘了这个知识,小学数学老师饶不了你 ) 高精度除低精度,原理是模

    2024年02月13日
    浏览(37)
  • 高精度加法,减法,乘法,除法(下)(C语言)

    前言 上一篇博客我们分享了高精度加法,减法,这一期我将为大家讲解高精度乘法和高精度除法。那让我们开始吧! 对加法和减法感兴趣的话就点我 让我们想想我们平时做数学时遇见乘法是怎么做的。以下图为例。 高精度乘法也是这样的一个思路,首先我们先把a和b的值储存

    2024年02月04日
    浏览(65)
  • 高精度加法,减法,乘法,除法(上)(C语言)

    前言 本篇内容介绍加法和减法,如果想看乘法和除法就点这里-高精度乘法,除法 加,减,乘,除这些运算我们自然信手捏来,就拿加法来说,我们要用c语言编程算a+b的和,只需让sum = a+b即可,可是这是局限的,我们都知道int的表示的最大值为2147483647(32位和64位机器)。但

    2024年02月03日
    浏览(40)
  • C++基础算法①——高精度加减法计算

    当我们利用计算机进行数值计算,有时候会遇到这样的问题: n!的精确结果是多少? 当n小于30的时候,我们当然可以通过电脑自带的计算器计算出来。但是当我们遇到 100! 的时候就没有办法直接计算出精确的结果。再比如,求两个20000位的数的和。 那怎么解决精度缺失的问

    2024年02月16日
    浏览(47)
  • 算法之高精度(含实例与详解)C语言

           高精度本质上是一种计算,由于int型和long long型的存储的数据大小有限。在有符号定义的情况下,int型为2的31次方减1;在无符号定义的情况下,lint型为2的32次方。因此过于巨大的数无法展示,这就用到了高精度来计算,其原理为将很大的数一位一位存在数组中,最后

    2024年02月06日
    浏览(36)
  • 求2的N次幂(C++)解决高精度运算

    ​👻内容专栏:《C/C++专栏》 🐨本文概括: 计算高精度的2的N次方数字。 🐼本文作者:花 碟 🐸发布时间:2023.6.22 为什么不直接利用int、float、double等类型进行存储计算,因为它们是存在有效数据范围的, 比如说 int 的范围是 -2147483648 ~ 2147483647 字节,数值最多占据10位,

    2024年02月10日
    浏览(35)
  • 【c++】算法:高精度(经典加减乘除){含解析(图解)}

    Hi~ o(* ̄▽ ̄*)ブ,今天来一起看看c++算法之高精度 之后会持续更新有关c++算法系列,欢迎观看!(#^.^#) 目录 前言 使用高精度的目的: 基本方法介绍:   一、A+B problem 基本思路解析: 具体步骤: 代码如下: 二、A-B problem 基本思路解析: ​编辑 具体步骤:  代码如下:  三

    2024年01月23日
    浏览(54)
  • C语言 加减乘除模 的 高精度计算 (超详细)

    目录 高精度加法 高精度乘法 高精度减法          高精度除法 高精度模法   高精度计算 是模拟算法的一种,通过字符串和整型数组的使用,将加减乘除的竖式运算 模拟 出来,达到计算的目的。其步骤大致分为:一,将字符串数据存到整型数组中,二,模拟算法,不同的

    2023年04月24日
    浏览(38)
  • Cordova插件开发二:高精度定位之卫星数据解析

    mapLocationObj值为配置文件封装的公共参数 res中返回的数据即为获取到的坐标数据 res = await this.returnNmeaDataNew(obj)即为高精度坐标数据获取方法 单次定位方法 getLocation中获取坐标并持续更新坐标值 卫星数据解析 持续更新坐标数据 将插件中获取的坐标数据返回

    2024年02月06日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包