高精度算法【加减乘除】

news/2024/5/19 20:07:33/文章来源:https://blog.csdn.net/weixin_54202947/article/details/127843808

全文目录

  • 😍 前言
  • 😀 高精度加法
    • 🤔 操作步骤
    • 😵‍💫 代码模板
  • 😀高精度减法
    • 🤔操作步骤
    • 😵‍💫 代码模板
  • 😀高精度乘法
    • 🤔操作步骤
    • 😵‍💫 代码模板
  • 😀 高精度除法
    • 🤔 操作步骤
    • 😵‍💫 代码模板

😍 前言

在实际应用中,语言提供的数据类型的最大值或最小值可能不足以支撑我们所进行的运算,这时会导致数据的溢出,所以我们需要一种算法来保证运算结果的精度。高精度运算就是为了解决这一问题而来的。简单来说,就是将数据的每一位的分开,存放在数组中,通过对数组中的每个位置来进行相应的运算来的得到最终结果。

需要注意的是:

1、由于数据过大,所以在进行输入的时候一般用字符串来进行存放

2、在将数据的每一位放进数组中时,最好是反着存放,也就是从前往后,位数依次升高。

以存放753 和 964 为例:
在这里插入图片描述

这样存放的好处在于方便进位,当他们需要进位的时,可以直接尾插。如果是正着存放的话每次进位都需要头插,全部数据都要往后挪,过于麻烦。

在这里插入图片描述
同样的在读取数据的时候需要从后往前读取,或者数据逆置一下。


😀 高精度加法

两数相加,数据的前后顺序不影响结果。

但是根据手算,如果是小数加大数的话,不方便进位,所以在进行运算前先保证大数在前,小数在后。方便进行进位运算

🤔 操作步骤

高精度加法的步骤:

a + b

1、将a 和 b 每一位的数据存放分开在数组A 和 B 中(A.size >= B.size)

2、用 t 来保存上一位进位的结果

3、从前往后,同时遍历A 和 Bt 分别加上两个数据的低位A[i] 和 B[i] ,得到这一位的运算结果

4、将这一位的结果的个位尾插进数组中保存起来(一次只能去一位数) ———> (t % 10

5、记录这一位的进位结果 ———> (t / 10

6、重复上述步骤,直到 A 遍历完(因为 A.size >= B.size ,所以 A 结束了,运算也就结束了)

7、最后一次运算可能还需要进位,将 t 中保留的进位结果尾插进数组


😵‍💫 代码模板

     A+  B—————————C
// C = A + B, A >= 0, B >= 0, A.size >= B.size
vector<int> add(vector<int> &A, vector<int> &B)
{if (A.size() < B.size())   // 保证位数大的 + 位数小的return add(B, A);vector<int> C;		// 保存运算结果int t = 0;		// 保存上一次的进位结果for (int i = 0; i < A.size(); i ++){t += A[i];		// 依次相加if (i < B.size())  	// 防止越界t += B[i];C.push_back(t % 10);	// 取余数保存起来t /= 10;		// 保留进位}if (t) 		// 最后可能还会有进位C.push_back(t);return C;
}

😀高精度减法

两数相减,数据的前后顺序会影响结果的正负性,但是结果的绝对值都是一样的。

但是小数减大数的话,借位不方便操作。所以我们在进行减法前先保证大数在前,小数在后。如果输入的是小数减大数的话提前输出 -

🤔操作步骤

高精度减法的步骤:
a - b

1、将a b 中的每一位的数据存放分开在数组A 和 B

2、如果b > a 提前输出 - ,进行 b - a

3、用 t 来保存上一位借位的结果

4、从前往后,同时遍历A 和 BA[i]分别减去 tB[i] ,得到这一位的运算结果

5、将这一位的结果的个位尾插进数组中保存起来 ———> ((t + 10) % 10
因为t 有可能是负数,需要取 10 + tt 为正数时 (t + 10) % 10 == t % 10,所以t需要先加上 10,再进行取模

6、如果 t 为负数,将 t 置为 1 来标记这一位的借位情况

7、重复上述步骤,直到 A 遍历完(因为 a >= b ,所以 A 结束了,运算也就结束了)

8、循环结束后,以 156 - 150 为例,结果可能会存在前导0,所以需要进行前导0 的去除

😵‍💫 代码模板

// 在进行减法之前需要先判断A >= B,如果A < b,先输出'-',然后进行B - A
// 可能会有前导0
bool cmp(vector<int>& a, vector<int>& b)
{// 如果长度不相等的话就可以立马得出结果if (a.size() != b.size()) return a.size() > b.size();// a和b的长度相等的情况,因为数据是反着存放的,所以也要反着比较for (int i = a.size(); i >= 0; i--){if (a[i] != b[i])return a[i] >= b[i];}// a == b的情况return true;
}A-  B—————————C
// C = A - B, 满足A >= B, A >= 0, B >= 0
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;		// 向A[i] 借位if (i < B.size()) 	// 减后的值t -= B[i];	C.push_back((t + 10) % 10);		// 负数要取10-t的结果,正数的话还是原来的数据if (t < 0) 	  // 如果现在的值是负数,标记tt = 1;   else t = 0;}// 去除前导0while (C.size() > 1 && C.back() == 0) C.pop_back();return C;
}

😀高精度乘法

这里以一个大数 a 乘以一个小数 b 为例。

🤔操作步骤

高精度乘法的步骤:
a * b

1、将a 中的每一位的数据存放分开在数组A

2、用 t 来保存上一位的结果

3、从前往后,遍历A A[i]乘以 b 再加上 t,得到这一位的运算结果

4、将这一位的结果的个位尾插进数组中保存起来 ———> (t % 10

5、保留需要进位的数据(t /= 10

6、重复上述步骤,直到 A 遍历完,并且 t 为0时结束。

7、循环结束后,以 1547 * 0 为例,结果可能会存在前导0,所以需要进行前导0 的去除

😵‍💫 代码模板

     A*  B—————————C
// 可能出现大数乘以0的情况
// C = A * b, A >= 0, b >= 0
vector<int> mul(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);	t /= 10;	// 保留需要进位的数据}// 去除前导0,可能会有*0的情况while (C.size() > 1 && C.back() == 0) C.pop_back();return C;
}

😀 高精度除法

这里以大数 a 除以 小数 b 为例。

因为除法是从高位开始运算的,所以得到的结果在入数组的时候也是从高位开始入的。为了跟前面的运算保持一致,所以需要在最后逆置数组。因为是一个位一个位进行运算,所以 a 中前几位可能除不尽 b ,所以需要去除前导0。

🤔 操作步骤

高精度除法的步骤:
a / b

1、将a 中的每一位的数据存放分开在数组A

2、用 r 来保存上一位的余数,

3、从前往后,遍历A r * 10 + A[i],得到这一位的除数

4、将这一位的结果尾插进数组中保存起来 ———> (r / b

5、保留余数(r %= b

6、重复上述步骤,直到 A 遍历完(剩下的余数不用管)

7、循环结束后,逆置数组。以 18954 / 88 为例,结果可能会存在前导0,所以需要进行前导0 的去除

😵‍💫 代码模板

	  	C————b|  a
// 因为除法是从高位开始运算的,所以入数组的时候也是从高位开始入,在最后需要逆置数组,
// 前几位可能比b小,除不尽b,需要去除前导0
// A / b = C ... r, A >= 0, b > 0
vector<int> div(vector<int> &A, int b, int &r)
{vector<int> C;r = 0;for (int i = A.size() - 1; i >= 0; i -- ){r = r * 10 + A[i];C.push_back(r / b);r %= b;}reverse(C.begin(), C.end());while (C.size() > 1 && C.back() == 0) C.pop_back();return C;
}

完结散花🌈🌈🌈
在这里插入图片描述

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

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

相关文章

基于SSM花卉商城设计与实现

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据疫情当下&#xff0c;你想解决的问…

记一道前端高难度面试题

目录 提问&#xff1a;如何让下面的这行代码成立 1.错误原因 2.思路 3.解题 4.小结 提问&#xff1a;如何让下面的这行代码成立 var [a,b] {a:1,b:2} 直接运行会报错&#xff0c;报错信息如下&#xff1a; Uncaught TypeError: {(intermediate value)(intermediate valu…

轻松学会jQuery选择器的用法

文章目录⛳️ 选择器✨ 属性选择器✨ 包含选择器✨ 位置选择器✨ 过滤选择器✨ 反向选择器⛳️ 快速投票⛳️ 选择器 本篇重点讲解jQuery中丰富的选择器&#xff0c;以及他们的基本用法。CSS的选择器均可以用jQuery的$进行选择&#xff0c;部分浏览器对CSS3的选择器支持不全&am…

【Pytorch with fastai】第 6 章 :其他计算机视觉问题

&#x1f50e;大家好&#xff0c;我是Sonhhxg_柒&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流&#x1f50e; &#x1f4dd;个人主页&#xff0d;Sonhhxg_柒的博客_CSDN博客 &#x1f4c3; &#x1f381;欢迎各位→点赞…

都说测试行业饱和了,为什么我们公司给初级测试开到了12K?

故事起因&#xff1a; 最近我有个刚毕业的学生问我说&#xff1a;我感觉现在测试行业已经饱和了&#xff0c;也不是说饱和了&#xff0c;是初级的测试根本就没有公司要&#xff0c;哪怕你不要工资也没公司要你&#xff0c;测试刚学出来&#xff0c;没有任何的项目经验和工作经验…

MaxViT: Multi-Axis Vision Transformer

论文&#xff1a;https://arxiv.org/abs/2204.01697 代码地址&#xff1a;https://github.com/google-research/maxvit 在本文中&#xff0c;介绍了一种高效且可扩展的注意力模型&#xff0c;称之为多轴注意力&#xff0c;该模型由两个方面组成&#xff1a;分块的局部注意力和…

笔记本电脑没有声音如何解决

​笔记本电脑没有声音的现象&#xff0c;也是笔记本电脑的常见运用病况之一,遇到这种情况的话,大家是否知道如何处理呢?下面小编来跟大家说说笔记本电脑没有声音解决方法&#xff0c;希望可以帮助到大家。 工具/原料&#xff1a; 系统版本&#xff1a;windows10系统 品牌型…

Allegro 274X格式gerber输出全流程详细介绍

Allegro 274X格式gerber输出全流程详细介绍 下面介绍Allegro gerber输出的全流程介绍 首先把光绘设置好 设置光钻孔精度 会出现对话框,勾选Enhanced Excellon format,点击close 输出钻孔文件,选择Auto Tool select,点击Drill 输出椭圆孔文件,默认设置,然后点击rout…

Android App开发之利用Glide实现图片的三级缓存Cache讲解及实战(附源码 超详细必看 简单易懂)

需要图片集和源码请点赞关注收藏后评论区留言~~~ 一、利用Glide实现图片的三级缓存 图片加载框架之所以高效&#xff0c;是因为它不但封装了访问网络的步骤&#xff0c;而且引入了三级缓存的机制。具体来说&#xff0c;是先到内存中查找图片&#xff0c;找到了就直接显示内存图…

二级导航栏

简介&#xff1a;本文通过HTML与CSS相集合的方式&#xff0c;来实现二级导航菜单。 HTML构建骨架 <body><ul class"nav1"><li>水果<ul class"nav2"><li>苹果</li><li>香梨</li><li>火龙果</li…

windows常见的命令操作大全

目录 一、目录文件操作 cd命令 dir命令 md命令 rd命令 move命令 copy命令 del命令 二、文本相关操作 type命令 >命令 findstr命令 |命令 三、网络相关操作 小建议&#xff1a;跟着文章亲手敲一遍是避免忘记的有效方法 一、目录文件操作 cd命令 功能&#xf…

JavaScript流程控制-循环(循环(for 循环,双重 for 循环,while 循环,do while 循环,continue break))

目录 JavaScript流程控制-循环 循环 for 循环 执行过程&#xff1a; 断点调试&#xff1a; 案例一&#xff1a;求1-100之间所有整数的累加和 案例二&#xff1a;求1-100之间所有数的平均值 案例三&#xff1a;求1-100之间所有偶数和奇数的和 案例四&#xff1a;求1-10…

HashMap的面试题

目录 1、底层数据结构 1.7和1.8有何不同 2、为什么用红黑树&#xff0c;为何不一上来就树化&#xff0c;树化阈值为何是8&#xff0c;何时会树化&#xff0c;何时会退化为链表 3、索引如何计算&#xff1f;hashCode都有了&#xff0c;为何还要提供hash()方法&#xff1f;数组…

ArcGIS计算地形湿度指数

TWI是区域地形对径流流向和蓄积影响的物理指标&#xff0c;有助于识别降雨径流模式、潜在土壤含水量增加区域和积水区域。 计算方法&#xff1a;TWI是通过细尺度地形与上梯度对地表面积的贡献相互作用&#xff0c;根据以下关系得到的(Beven et al.,1979) [1] : TWI ln [CA/…

用专业团队管理软件工具轻松“拿捏”年轻运营团队

本文旨在抛砖引玉&#xff0c;欢迎大家拍砖讨论&#xff0c;通过一款时下流行的专业团队管理软件飞项做案例&#xff0c;一起探讨和交流团队管理专业工具软件和一些对应的方法论。 说到国内这几年流行起来的团队管理工具软件&#xff0c;我们先看看互联网这几年的发展。这几年&…

京东面试题:ElasticSearch 深度分页解决方案

前言 Elasticsearch 是一个实时的分布式搜索与分析引擎&#xff0c;在使用过程中&#xff0c;有一些典型的使用场景&#xff0c;比如分页、遍历等。 在使用关系型数据库中&#xff0c;我们被告知要注意甚至被明确禁止使用深度分页&#xff0c;同理&#xff0c;在 Elasticsearc…

【Python实战】听书就用它了:海量资源随便听,内含几w书源,绝对精品哦~(好消息好消息)

前言 有温度 有深度 有广度 就等你来关注哦~ 所有文章完整的素材源码都在&#x1f447;&#x1f447; 粉丝白嫖源码福利&#xff0c;请移步至CSDN社区或文末公众hao即可免费。 哈喽&#xff01;我是栗子同学&#xff0c;继续更新——今天聊一聊“西马拉雅”。&#xff08;谐音…

特征选择-sklearn

sklearn特征选择:移除低方差特征&#xff1a;单变量特征选择递归特征消除基于模型的SelectFromModel顺序特征选择特征选择作为pipline的一部分sklearn.feature_selection模块中的类可用于样本集的特征选择/降维&#xff0c;以提高估计器的准确性得分或提高其在非常高维的数据集…

BL200OPC UA分布式IO系统接线方式

BL200OPC UA 数据点 Node Id OPC UA 的 Node Id 默认是 NS1&#xff1b;SI/O 数据点的 Modbus 映射地址(如首个 DO 模 块第一路 DO&#xff1a;NS1&#xff1b;S1000)&#xff0c;具体 Modbus 映射地址参考 5.1.4Modbus 寄存器映射&#xff0c; 如果是自定义的 OPC UA 模型 Nod…

(02)Cartographer源码无死角解析-(19) SensorBridge→雷达点云数据预处理(函数重载)

本人讲解关于slam一系列文章汇总链接:史上最全slam从零开始&#xff0c;针对于本栏目讲解(02)Cartographer源码无死角解析-链接如下: (02)Cartographer源码无死角解析- (00)目录_最新无死角讲解&#xff1a;https://blog.csdn.net/weixin_43013761/article/details/127350885 …