高精度算法【加减乘除】

news2025/7/15 21:00:12

全文目录

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

😍 前言

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

需要注意的是:

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) 	  // 如果现在的值是负数,标记t
        	t = 1;   
        else 
        	t = 0;
    }

	// 去除前导0
    while (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.coloradmin.cn/o/8492.html

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

相关文章

[R]第二节 对象介绍与赋值运算

前言 R 创建、控制的实体(entity)称为对象(object)。向量(vector)矩阵(matrix)数组(array)数据框(data frame)列表(list)因子(factor)函数(function)通过以上实体定义的更为一般性的结构(structures) 数据的存储形式 R语言进行数据存储选择一种合适的数据结构将已有的数据输入…

【Python实战】海量表情包炫酷来袭,快来pick斗图新姿势吧~(超好玩儿)

前言 有温度 有深度 有广度 就等你来关注哦~ 所有文章完整的素材源码都在&#x1f447;&#x1f447; 粉丝白嫖源码福利&#xff0c;请移步至CSDN社区或文末公众hao即可免费。 你有在聊天中遇到不知道该如何表达&#xff0c;如何回复的情况吗&#xff1f; 或许&#xff0c;使…

FastDFS学习(四)

目录&#xff1a; &#xff08;1&#xff09;FastDFS搭建集群的环境准备 &#xff08;2&#xff09;FastDFS集群搭建负载均衡环境-使用Nginx进行负载均衡 &#xff08;1&#xff09;FastDFS搭建集群的环境准备 架构图 如果你公司刚好用这个&#xff0c;那你就会搭建集群涉及…

python基于PHP+MySQL的个人博客系统毕设

随着时代和网络的发展,人们越来越希望通过多种模式来展示自己。于是个人博客就出现了,它可以更好的让人们来记录自己的工作和学习方式。博客不仅仅可以让自己抒发个人感情,还可以展示自己真实的生活,从而建立起一种友好的交友平台。 PHP个人博客系统毕设系统分为前台和后台两部…

第2-3-3章 文件处理策略-文件存储服务系统-nginx/fastDFS/minio/阿里云oss/七牛云oss

文章目录5.2 文件处理策略5.2.1 FileStrategy5.2.2 AbstractFileStrategy5.2.3 LocalServiceImpl5.2.4 FastDfsServiceImpl5.2.5 AliServiceImpl5.2.6 MinioServiceImpl5.2 文件处理策略 在开发fastDFS和minio实现类之前&#xff0c;需要提前安装部署好fastDFS和minio。搭建教程…

LIS.LCS.LCIS相关问题

文章目录P1020 [NOIP1999 普及组] 导弹拦截P1439 【模板】最长公共子序列P1637 三元上升子序列272. 最长公共上升子序列LCISP1020 [NOIP1999 普及组] 导弹拦截 P1020 [NOIP1999 普及组] 导弹拦截 导弹拦截应该是接触DP的第一题&#xff08;只不过洛谷上的数据加强了&#xff…

Windows平台 使用jarsigner对Apk签名

使用的是JDK自带的jarsigner工具来完成Apk签名 1) 首先找到你的Java Jdk中bin的路径&#xff1a;C:\Program Files\Java\jdk1.8.0_152\bin jarsigner简单使用说明 #jarsigner的命令格式&#xff1a; jarsigner -verbose -keystore [您的私钥存放路径] -signedjar [签名后文件存…

使用高数值孔径透镜进行脉冲聚焦

摘要 尽管对于大多数其他类型的光源而言&#xff0c;静态近似下是足够精确的&#xff0c;但对于超短脉冲来说需要更加精确的方法&#xff0c;其中要考虑到不同光谱模式之间的相关性。在此&#xff0c;我们在空间、时间与场分布上研究了该脉冲传播通过高数值孔径透镜的影响。 建…

基于matlab和Simulink的不同阶QAM调制解调系统误码率对比仿真

目录 1.算法概述 2.仿真效果预览 3.核心MATLAB预览 4.完整MATLAB程序 1.算法概述 正交振幅调制是利用已调信号在相同带宽内的频谱正交来实现两路并行的数据信息传输&#xff0c;其信道频带利用率与单边带调制一样&#xff0c;主要用于高速数据传输系统中。QAM系统组成框图如…

Vue3 - 事件 API 新标准(如何在 Vue3 中怎么用事件总线实现兄弟组件通信?相比 Vue2 有什么不同?)

前言 对比 Vue2 &#xff0c;引出并展开 Vue3 。 本文讲述了事件 API 在 Vue3 中相比 Vue2 有什么变化&#xff0c;以及使用方法和代码示例详细讲解。 回忆 Vue2 大家在写 Vue2 项目时&#xff0c;兄弟组件之间传参&#xff0c;我相信很大一部分开发者都会借助全局的事件总线&…

Kubernetes 系统化学习之 POD原理篇(二)

1. Kubernets 概览回顾 Pod、Service、Volume 和 Namespace 是 Kubernetes 集群中四大基本对象&#xff0c;它们能够表示系统中部署的应用、工作负载、网络和磁盘资源&#xff0c;共同定义了集群的状态。Kubernetes 中很多其他的资源其实只对这些基本的对象进行了组合。 Pod -…

最全JAVA系列视频教程源码

扫描关注公众号&#xff1a;发送对应消息获取源码&#xff08;下面红色字为发送消息内容,取掉空格哦&#xff09; JAVA 基础&#xff1a; java基础 更适合零基础学员&#xff1a; 自Java语言起源始&#xff0c;循序渐进&#xff0c;知识点剖析细致且每章配备大量随堂练…

Android实现动态换肤-原理篇

学习是一个过程。 文章目录Activity中LayoutInflater加载布局总体时序图LayoutInflater源码讲解&#xff08;api28&#xff09;LayoutInflater设置Factory2实现方式LayoutInflater源码总结Activity中LayoutInflater加载布局总体时序图 LayoutInflater源码讲解&#xff08;api28…

高级UI——Paint(滤镜,颜色通道,矩阵运算)

前言 我们已经详细了解到整个android程序&#xff0c;从启动再到绘制的整体流程&#xff0c;从这中间我们又牵扯出了Canvas绘制图形的画板和我们的Paint控制色彩样式的画笔&#xff0c;那么之前基础篇我们就不进行详细的解释&#xff0c;那些API在之前的基础篇已经公布出来&am…

Typescript 函数类型详解

Typescript 函数 前言 虽然 JS/TS 支持面向对象编程&#xff0c;但大部分时候还是在写函数。函数是一等公民。本文介绍下如何在 TypeScript 中使用函数&#xff0c;包括&#xff1a; 函数类型声明函数参数类型&#xff1a;可选参数、默认参数、剩余参数函数返回值类型this 类…

java#5(数组)

目录 数组 1.数组的完整格式:数据类型[] 数组名 new 数据类型[]{元素1,元素2......}; 2.数组的简化格式:数据类型[] 数组名 {元素1,元素2......}; 3.数组的地址​编辑 4.数组的索引(下标,角标) 5.length的使用(表示数组的长度:有几个元素) 6.数组动态初始化:初始化时指…

Redis事务入门及命令

文章目录Redis 事务入门及命令事务概念Redis 事务概念Redis 事务特性Redis 三个阶段入门代码示例Redis 相关命令MULTIDISCARDEXECWATCHUNWATCHRedis 事务入门及命令 事务概念 数据库事务( transaction )是访问并可能操作各种数据项的一个数据库操作序列&#xff0c;这些操作要…

详解 YUV,一文搞定 YUV 是什么!

YUV 是一个颜色模型&#xff0c;通常用作彩色图像管道的一部分。它对彩色图像或视频进行编码时考虑到了人类的感知&#xff0c;与“直接”的 RGB 表示相比&#xff0c;允许减少色度分量的带宽。历史上&#xff0c;术语 YUV 和 Y’UV 用于电视系统中颜色信息的特定模拟编码。今天…

HTML学生作业网页:使用HTML+CSS技术实现传统文化网页设计题材-西安事变历史纪念馆 10页 带视频 带音乐

Web前端开发技术 描述 网页设计题材&#xff0c;DIVCSS 布局制作,HTMLCSS网页设计期末课程大作业 | 茶文化网站 | 中华传统文化题材 | 京剧文化水墨风书画 | 中国民间年画文化艺术网站 | HTML期末大学生网页设计作业 HTML&#xff1a;结构 CSS&#xff1a;样式 在操作方面上运…

《上海悠悠接口自动化平台》-4.注册用例集实战演示

前言 以注册接口为例&#xff0c;在平台上演示如何维护接口自动化用例 访问地址http://47.108.155.10/login.html 用户名: demo, 密码: demo123 有兴趣的可以自己去查看用例规范 和 运行效果。 API 接口层 先找出注册接口的接口文档&#xff0c;以下是接口文档部分 主要关…