C++高精度问题

news2024/11/18 16:38:41

高精度前言

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.coloradmin.cn/o/1407078.html

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

相关文章

国标GB28181协议EasyCVR启动失败报错“Local Machine Check Error”的解决方法

国标GB28181安防监控系统EasyCVR平台采用了开放式的网络结构&#xff0c;可支持4G、5G、WiFi、有线等方式进行视频的接入与传输、处理和分发。安防视频监控平台EasyCVR还能支持GIS电子地图模式&#xff0c;基于监控摄像头的经纬度地理位置信息&#xff0c;将场景中的整体安防布…

感性负载对电路稳定性有什么影响?

感性负载是指带有电感元件的负载&#xff0c;如电动机、变压器等。在电路中&#xff0c;感性负载对电路稳定性有很大的影响。本文将从以下几个方面来分析感性负载对电路稳定性的影响&#xff1a; 当感性负载接通或断开时&#xff0c;会产生一个瞬时电流&#xff0c;这个瞬时电流…

大数据开发之Spark(RDD弹性分布式数据集)

第 1 章&#xff1a;rdd概述 1.1 什么是rdd rdd&#xff08;resilient distributed dataset&#xff09;叫做弹性分布式数据集&#xff0c;是spark中最基本的数据抽象。 代码中是一个抽象类&#xff0c;它代表一个弹性的、不可变、可分区、里面的元素可并行计算的集合。 1.1…

安装vcenter7.0问题汇总

1.Windows server 2016安装vcenter7.0出现&#xff1a;无法获取目标服务器证书的 SSL 指纹。 第一个检查点&#xff1a; 防火墙&#xff1a;关闭或者开放443端口 第二个检查点&#xff1a; 检查自己的虚拟网卡是否开启 第三个检查点&#xff1a; 我标记的第一个大框中我这…

Zabbix分布式监控系统

实验过程 ps&#xff1a; 阿里云盘Xnode1获取 xnode1 https://www.alipan.com/s/HgLXfoeBWG2 提取码: eb70 1、xnode1克隆两台虚拟机并修改ip zabbix-server192.168.224.3 zabbix-agent192.168.224.4 2、修改主机名 [rootlocalhost ~]# hostnamectl set-hostname zabbix-se…

Vue3 ref与reactive

✨ 专栏介绍 在当今Web开发领域中&#xff0c;构建交互性强、可复用且易于维护的用户界面是至关重要的。而Vue.js作为一款现代化且流行的JavaScript框架&#xff0c;正是为了满足这些需求而诞生。它采用了MVVM架构模式&#xff0c;并通过数据驱动和组件化的方式&#xff0c;使…

php比较运算,强相等(===)弱相等(==)表

弱相等&#xff08;&#xff09; 符号为&#xff1a; 规则为&#xff1a;只比较值&#xff0c;不比较类型&#xff0c;只要值对就为true 样例&#xff1a;比较整型123和字符串"123"&#xff0c;运行结果给出了true 弱相等表&#xff1a;* 代表在 PHP 8.0.0 之前为…

【网站项目】新冠疫情隔离人员信息管理系统(有源码)

🙊作者简介:多年一线开发工作经验,分享技术代码帮助学生学习,独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。🌹赠送计算机毕业设计600个选题excel文件,帮助大学选题。赠送开题报告模板,帮助书写开题报告。作者完整代码目录供你选择: 《Springboot网站项目…

S7-1500与多台200SMART之间无线以太网通讯搭建方法

这是一个不用编程即可瞬间实现S7-200smart与S7-1500的以太网通讯的方法&#xff0c;这种控制方式下最多可以控制128台S7-200SMART。本方案以组态王与S7-1500和2台S7-200smart为例&#xff0c;介绍S7-1500与多台 S7-200smart在Profinet协议下的自组网无线通信实现过程。在本方案…

大数据平台红蓝对抗 - 磨利刃,淬精兵!

背景 目前大促备战常见备战工作&#xff1a;专项压测&#xff08;全链路压测、内部压测&#xff09;、灾备演练、降级演练、限流、巡检&#xff08;监控、应用健康度&#xff09;、混沌演练&#xff08;红蓝对抗&#xff09;&#xff0c;如下图所示。随着平台业务越来越复杂&a…

AI一键换衣,阿里Outfit Anyone来了,电商人的福音!

继谷歌推出Tryon Diffusion虚拟试穿后&#xff0c;国内的头部电商阿里也推出的Outfit Anyone虚拟试穿技术。该技术采用双流条件扩散模型&#xff0c;处理模特和服装数据&#xff0c;通过衣物图像实现逼真的虚拟试穿效果&#xff0c;结合Animate Anyone技术&#xff0c;轻松制作…

5118优惠码vip、svip、专业版和旗舰版使用yhm666

5118大数据平台会员优惠码【yhm666】&#xff0c;结算时勾选“使用优惠码”&#xff0c;然后在优惠码窗口中输入yhm666&#xff0c;然后点确定即可享受特价会员价格。阿腾云atengyun.com分享如下图&#xff1a; 5118会员优惠码【yhm666】 5118会员价格和使用优惠码之后的价格对…

Go 复合数据类型

1. 数组&#xff08;array&#xff09;&#xff08;OK&#xff09; 数组数组的概念数组是具有固定长度且拥有零个或多个相同数据类型元素的序列 i. 元素的数据类型相同 ii. 长度固定的序列 iii. 零个或多个元素的序列 与 slice 对比 由于数组的长度固定&#xff0c;所以在 G…

电脑硬盘数据恢复?这3个方法不要错过!

“我在使用电脑办公时&#xff0c;不小心将电脑硬盘里的数据误删了。这些数据对我来说都是比较重要的&#xff01;有什么比较简单的方可以恢复吗&#xff1f;” 电脑硬盘中一般会保存用户很多重要的资料和数据&#xff0c;如果这些资料误删了&#xff0c;可能会带来各种麻烦和不…

自定义线程工厂规范【开发手册】

一、介绍 最近在看一些编码以及设计的规范&#xff0c;觉得有些还是很有用的&#xff0c;在这分享给大家。主要学习阿里的Java开发规范&#xff08;黄山版&#xff09;&#xff0c;这篇主要是对日常大家使用线程池或者线程时&#xff0c;为何应该制定有意义的线程名称等。 二…

Kafka-服务端-副本机制

Kafka从0.8版本开始引入副本(Replica)的机制&#xff0c;其目的是为了增加Kafka集群的高可用性。 Kafka实现副本机制之后&#xff0c;每个分区可以有多个副本&#xff0c;并且会从其副本集合(Assigned Replica,AR)中选出一个副本作为Leader副本&#xff0c;所有的读写请求都由…

快速上手的AI工具-文心一言辅助学习

前言 大家好晚上好&#xff0c;现在AI技术的发展&#xff0c;它已经渗透到我们生活的各个层面。对于普通人来说&#xff0c;理解并有效利用AI技术不仅能增强个人竞争力&#xff0c;还能在日常生活中带来便利。无论是提高工作效率&#xff0c;还是优化日常任务&#xff0c;AI工…

数据管理平台Splunk Enterprise本地部署并结合内网穿透实现远程访问

文章目录 前言1. 搭建Splunk Enterprise2. windows 安装 cpolar3. 创建Splunk Enterprise公网访问地址4. 远程访问Splunk Enterprise服务5. 固定远程地址 前言 本文主要介绍如何简单几步&#xff0c;结合cpolar内网穿透工具实现随时随地在任意浏览器&#xff0c;远程访问在本地…

vue3项目中使用vite-plugin-mock

1、安装插件 npm i mockjs vite-plugin-mock --save-dev 2、修改配置文件 vite.config.js import { viteMockServe } from vite-plugin-mock plugins: [vue(), viteMockServe({ supportTs:false, logger: false, mockPath: "/mock/" // 注…

宝宝洗衣机好吗?高性价比的婴儿洗衣机推荐

随着大家生活水平的提高&#xff0c;越来越多人追求品质化生活。从洗衣服这件基础小事中就能看出&#xff0c;从比较早的解放双手&#xff0c;到追求衣物的洗护&#xff0c;再到近些年来&#xff0c;大人小孩衣服分区洗衣的精致生活理念。如今&#xff0c;洗衣机市场根据消费者…