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初始为0int 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 要在最高位补1if(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;}//去除前导0while(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函数删除前导0reverse(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.mzph.cn/news/643368.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Power Apps 向Power Automate传一个数组参数

Power Apps传Power Automate数组参数 背景Power Apps传参方法画布开发我们现在power apps中设置一个集合**ArrCollect**准备一个按钮 Power Automate接收总结画布流 背景 我们通常会从Power Apps界面传递参数给Flow中&#xff0c;但是很多时候仅仅是一个字符串类型的已经不适用…

二进制计算

二进制的引入 十进制规则:满10进1&#xff0c;由数字0到9组成。 而所谓十六进制&#xff0c;八进制&#xff0c;二进制的规则也是类似。 这里为了区分十六进制和八进制&#xff0c;十六进制前面会加上0x&#xff0c;八进制前面会加个0作为区分 而二进制的规则类似于十进制&…

openssl3.2/test/certs - 025 - client intermediate ca: cca-cert

文章目录 openssl3.2/test/certs - 025 - client intermediate ca: cca-cert概述笔记END openssl3.2/test/certs - 025 - client intermediate ca: cca-cert 概述 openssl3.2 - 官方demo学习 - test - certs 笔记 // \file my_openssl_linux_log_doc_025.txt // \note open…

PLC协议转BACnet网关BA107

随着通讯技术和控制技术的发展&#xff0c;为了实现楼宇的高效、智能化管理&#xff0c;集中监控管理已成为楼宇智能管理发展的必然趋势。在此背景下&#xff0c;高性能的楼宇暖通数据传输解决方案——协议转换网关应运而生&#xff0c;广泛应用于楼宇自控和暖通空调系统应用中…

精品基于Uniapp+springboot智能家居环境检测App

《[含文档PPT源码等]精品基于Uniappspringboot智能家居环境检测App》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程、包运行成功&#xff01; 软件开发环境及开发工具&#xff1a; 开发语言&#xff1a;Java 后台框架&#xff1a;springboot、ssm …

HTTP3/QUIC 性能测试与配套组件

背景 最近一年很多关于QUIC的文章层出&#xff0c;但是发现一个问题&#xff0c;这些文章都是在介绍QUIC或HTTP3是怎样的一个东西&#xff0c;以及它的优点和机制&#xff0c;将它夸的近乎上天了。然而有心的人估计会亲手做一些测试&#xff0c;就会发现这个被捧上天的东西性能…

宝塔+nextcloud+docker+Onlyoffice 全开启https

折腾了我三天的经验分享 1.宝塔创建网站 nextcloud版本为28.0.1 php8.2 &#xff0c;导入nextcloud绑定域名对应的证书 &#xff0c;不用创建mysql 因为nextcloud 要求是mariadb:10.7 宝塔里没有&#xff0c;就用docker安装一个 端口设置为3307 将数据库文件映射出来/ww…

Leetcode刷题(二十八)

找出字符串中第一个匹配项的下标&#xff08;Easy&#xff09; 给你两个字符串 haystack 和 needle &#xff0c;请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标&#xff08;下标从 0 开始&#xff09;。如果 needle 不是 haystack 的一部分&#xff0c;则返…

基于springboot+vue的“衣依”服装销售平台系统(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 研究背景…

maven详细介绍

1.简介 Maven是一个基于项目对象模型&#xff08;POM&#xff09;的软件项目管理工具&#xff0c;主要用于Java项目的构建、依赖管理和项目信息管理。通过一小段描述信息&#xff0c;Maven能够管理项目的构建、报告和文档等各个环节。它提供了一种标准化的构建方式&#xff0c…

VSCode Debug 参数设置说明

如果想在vscode中debug一个项目&#xff0c;比如python3 run.py --args 这个时候你需要着重关注几个参数&#xff0c;参数用两个双引号分开&#xff0c;不能有空格。 cwd :运行代码的基础目录env: 设置环境变量 PYTHONPATH&#xff1a; 设置项目用到的模块搜索路径&#xff…

361. 观光奶牛(小数二分,spfa判断正环,01分数规划)

361. 观光奶牛 - AcWing题库 给定一张 L 个点、P 条边的有向图&#xff0c;每个点都有一个权值 f[i]&#xff0c;每条边都有一个权值 t[i]。 求图中的一个环&#xff0c;使“环上各点的权值之和”除以“环上各边的权值之和”最大。 输出这个最大值。 注意&#xff1a;数据保…

SpringBoot 整合RabbitMQ 之延迟队列实验

在Spring Boot中整合RabbitMQ并实现延迟队列的功能&#xff0c;可以按照以下步骤进行&#xff1a; 添加依赖&#xff1a;在pom.xml文件中添加RabbitMQ和Spring AMQP相关的依赖。 <dependency><groupId>org.springframework.boot</groupId><artifactId&g…

在PyCharm中安装GitHub Copilot插件,login之后报出如下错误:

Sign in failed. Reason: Request signInInitiate failed with message: connect ECONNABORTED 20.205.243.166:443, request id: 7, error code: -32603 前提&#xff1a; 设置网址&#xff1a;https://github.com/settings/copilot&#xff0c;已设置为允许 或者&#xff1…

速盾:服务器接入CDN后上传图片失败的解决方案

本文将探讨当服务器接入CDN后&#xff0c;上传图片失败的常见原因&#xff0c;并提供解决方案以解决这些问题。同时&#xff0c;我们还将附上一些相关的问题和解答&#xff0c;让读者更好地理解和应对这些挑战。 随着互联网的持续发展&#xff0c;网站的性能和速度对于用户体验…

Java基础面试题-4day

异常 Exception和Error有什么区别&#xff1f; Exception类和Error类有一个共同的父类Throwable类 Exception类为异常类&#xff0c;可以使用catch 捕获&#xff0c;捕获之后&#xff0c;Exception类又分为Checked Exception和 Uncheckend Exception Checked Exception是捕获…

工业智能网关储能物联网应用实现能源的高效利用及远程管理

储能电力物联网是指利用物联网技术和储能技术相结合&#xff0c;实现对电力系统中各种储能设备的智能管理和优化控制。随着可再生能源的不断发展和应用&#xff0c;电力系统面临着越来越大的电力调度和储能需求而储能电力物联网的出现可以有效解决这一问题&#xff0c;提高电力…

Spring5系列学习文章分享---第三篇(AOP概念+原理+动态代理+术语+Aspect+操作案例(注解与配置方式))

目录 AOP概念AOP底层原理AOP(JDK动态代理)使用 JDK 动态代理&#xff0c;使用 Proxy 类里面的方法创建代理对象**编写** **JDK** 动态代理代码 AOP(术语)AOP操作&#xff08;准备工作&#xff09;**AOP** **操作&#xff08;**AspectJ注解)**AOP** **操作&#xff08;**AspectJ…

oracle data block , extent 和segment区别

data block是数据库中最小的逻辑存储单元。当数据库的对象需要更多的物理存储空间时&#xff0c;连续的data block就组成了extent . 一个数据库对象拥有的所有extents被称为该对象的segment. Data block、extent和segment是数据库中不同层次的数据存储和管理单位&#xff0c;它…

Vue 点击按钮复制内容到系统剪贴板

Vue 点击按钮复制内容到系统剪贴板 使用navigator将内容添加到系统剪贴板 <template><div><button click"copy">点击复制</button></div> </template><script>export default {name: CopyTest,data() {return {copyCont…