C++高精度问题

高精度前言

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

高精度总体思路

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

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

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

高精度算法

高精度加法

示例题目:

我们一般习惯是加法从个位数开始运算, 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。

高精度减法

示例题目: 

减法计算思路与加法相似

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

借位的计算

如果这次的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的情况

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

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

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

高精度乘法

示例题目:

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

与加法十分类似,所以具体思路参考加法,需要注意的是,乘法也需要去前导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;
}

高精度除法

实例题目

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

模拟除法过程我们可以发现,每次的被除数是上次计算得到的余数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

此篇为学习之余的总结,作为笔记使用,如果有错误还请指正,谢谢!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/343934.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据分析的理念、流程、方法、工具(下)

四、用户分群 1、用户分群 用户分群是精细化运营的基础要求&#xff0c;也是数据分析的最基础方式。对用户进行分群&#xff0c;能帮助我们了解每个细分群体用户的变化情况&#xff0c;进而了解用户的整体现状及发展趋势。同时&#xff0c;由于运营资源本身有限&#xff0c;不…

web开发学习笔记(14.mybatis基于xml配置)

1.基本介绍 2.基本使用 在mapper中定义 在xml中定义&#xff0c;id为方法名&#xff0c;resultType为实体类的路径 在测试类中写 3. 动态sql&#xff0c;if和where关键字 动态sql添加<where>关键字可以自动产生where和过滤and或者or关键字 where关键字可以动态生成whe…

【论文阅读|2024 WACV 多目标跟踪Deep-EloU】

论文阅读|2024 WACV 多目标跟踪Deep-EloU 摘要1 引言&#xff08;Introduction&#xff09;2 相关工作&#xff08;Related Work&#xff09;2.1 基于卡尔曼滤波器的多目标跟踪算法&#xff08;Multi-Object Tracking using Kalman Filter&#xff09;2.2 基于定位的多目标跟踪…

云原生网关哪家强:Sealos 网关血泪史

作者&#xff1a;Sealos 创始人&#xff0c;环界云计算 CEO 方海涛 Sealos 公有云 &#xff08;https://cloud.sealos.io&#xff09; 几乎打爆了市面上所有主流的开源网关&#xff0c;本文可以给大家很好的避坑&#xff0c;在网关选型方面做一些参考。 Sealos Cloud 的复杂场…

opencv011 滤波器03 高斯滤波

今天来学习一下高斯滤波&#xff01;高斯滤波是一种线性平滑滤波&#xff0c;适用于消除高斯噪声&#xff0c;广泛应用于图像处理的减噪过程。通俗的讲&#xff0c;高斯滤波就是对整幅图像进行加权平均的过程&#xff0c;每一个像素点的值&#xff0c;都由其本身和邻域内的其他…

Android开发之状态栏布局隐藏的方法

1.问题如下&#xff0c;安卓布局很不协调 2.先将ActionBar设置为NoActionBar 先打开styles.xml 3.使用工具类 package com.afison.newfault.utils;import android.annotation.TargetApi; import android.app.Activity; import android.content.Context; import android.graph…

Python实现两因素独立设计方差分析,简单效应分析

# Python实现两因素独立设计方差分析 1. 背景 1. 有研究者探讨了在不同企业文化下&#xff0c;管理者的不同语言风格所产生的影响 有的企业注重员工的独立性&#xff0c;强调个人努力和内部竞争&#xff1b;有的企业注重员工的整体性&#xff0c;强调团队合作和团队绩效。 …

MySQL函数—数值函数,随机数验证码生成

MySQL函数—日期函数 函数功能CEIL(x)向上取整FLOOR(x)向下取整MOD(x,y)返回x/y的模&#xff08;取余&#xff09;RAND()返回0-1的随机数ROUND(x,y)求参数x的四舍五入&#xff0c;保留y位小数 1、向上取整&#xff1a;CEIL。只要小数点后的数字大于0就取整。 select CEIL(1.2…

《Linux C编程实战》笔记:信号的发送

信号的发送主要由函数kill、raise、sigqueue、alarm、setitimer以及abort来完成 kill函数 kill函数用来发送信号给指定的进程。 #include<sys/types.h> #include<signal.h> int kill(pid_t pid,int sig); 该函数的行为与第一个参数pid有关&#xff0c;第二个参…

开源模型应用落地-业务整合篇(四)

一、前言 通过学习第三篇文章&#xff0c;我们已经成功地建立了IM与AI服务之间的数据链路。然而&#xff0c;我们目前面临一个紧迫需要解决的安全性问题&#xff0c;即非法用户可能会通过获取WebSocket的连接信息&#xff0c;顺利地连接到我们的服务。这不仅占用了大量的无效连…

jenkins安装配置,使用Docker发布maven项目全过程记录(2)

2、使用Docker发布Maven项目过程的配置 首先说明&#xff0c;在这里仅介绍我使用Jenkins的发布过程的配置&#xff0c;不涉及Dockerfile、docker-compose.yml文件的内容。 2.1 创建Item 在这里&#xff0c;输入item名称&#xff0c;我使用的Freestyle project&#xff0c;点击…

MSP430仿真器使用常见问题

一、 主要是驱动安装问题 有用户反应驱动安装不上&#xff0c;按照用户手册操作一直不能安装成功。 可以尝试如下步骤进行安装。 1. 双击设备管理器中无法安装或者提示有错误的430仿真器设备 选择驱动程序——更新驱动程序 选择手动安装 选择从电脑设备驱动列表中安装 弹出下…

Spring Security 6 学习-1

什么是 Spring Security Spring Security文档 Spring Security中文文档 Spring Security 是 Spring 家族中的安全型开发框架&#xff0c;主要解决三大方面问题&#xff1a;认证&#xff08;你是谁&#xff09;、授权&#xff08;你能干什么&#xff09;、常见攻击保护&#xff…

mysql INSERT数据覆盖现有元素(若存在)

INSERT...ON DUPLICATE KEY UPDATE的使用 如果指定了ON DUPLICATE KEY UPDATE&#xff0c;并且插入行后会导致在一个UNIQUE索引或PRIMARY KEY中出现重复值&#xff0c;则会更新ON DUPLICATE KEY UPDATE关键字后面的字段值。 例如&#xff0c;如果列a被定义为UNIQUE&#xff0…

机器学习实验3——支持向量机分类鸢尾花

文章目录 &#x1f9e1;&#x1f9e1;实验内容&#x1f9e1;&#x1f9e1;&#x1f9e1;&#x1f9e1;数据预处理&#x1f9e1;&#x1f9e1;代码认识数据相关性分析径向可视化各个特征之间的关系图 &#x1f9e1;&#x1f9e1;支持向量机SVM求解&#x1f9e1;&#x1f9e1;直觉…

JavaEE-Nuxt中的vuex

Nuxt中的vuex 参考&#xff1a;https://v2.nuxt.com/docs/directory-structure/store 3.1 根模块数据操作 步骤一&#xff1a;创建 store/index.js 添加一个 counter变量&#xff0c;并可以继续累加操作 export const state () > ({counter: 0 })export const mutations …

用户反映在浏览器中使用AI工具 Copilot 遇到严重卡顿问题,微软官方给出初步解释

近日&#xff0c;多位用户反馈在使用Edge和Chrome浏览器中的Copilot时出现卡顿问题&#xff0c;甚至需要重启浏览器才能解决。对此&#xff0c;微软广告和网络服务部门CEO米哈伊尔帕拉欣表示&#xff0c;问题可能与Edge浏览器的“效率模式”有关。 微软中国官方网址链接&#x…

【GitHub项目推荐--12 年历史的 PDF 工具开源了】【转载】

最近在整理 PDF 的时候&#xff0c;有一些需求普通的 PDF 编辑器没办法满足&#xff0c;比如 PDF 批量合并、编辑等。 于是&#xff0c;我就去 GitHub 上看一看有没有现成的轮子&#xff0c;发现了这个 PDF 神器「PDF 补丁丁」&#xff0c;让人惊讶的是这个 PDF 神器有 12 年的…

C#,计算几何,鼠标点击绘制 (二维,三次)B样条曲线的代码

B样条&#xff08;B-Spline&#xff09;是常用的曲线拟合与插值算法之一。 这里给出在 Form 的 图像 Picturebox 组件上&#xff0c;按鼠标点击点绘制 &#xff08;三次&#xff09;B样条曲线的代码。 2022-12-05 修改了代码。 1 文本格式 using System; using System.Data; …

机器人制作开源方案 | 智能特殊环境清洗机器人

作者&#xff1a;达德聪 袁豪杰 杨垚 单位&#xff1a;邢台学院 指导老师&#xff1a;王承林 杨立芹 智能特殊环境清洗机器人基于STC系列单片机为核心&#xff0c;驱动摄像头模块、超声波模块、ESP8266无线模块、自动寻迹模块、舵机模块、语音识别模块&#xff0c;实现自主寻…
最新文章