【算法之路】高精度算法(实现加减乘除)

news2024/10/6 12:18:55

目录

一、高精度概念

二、高精度算法的实现

1、高精度加法(大整数相加)

2、高精度减法(大整数减法)

3、高精度乘法(大整数*小整数)

4、高精度除法(大整数/小整数)


一、高精度概念

高精度算法,是一种处理大数字的数学计算方法。在一般的科学计算中,会经常算到小数点后几百位或者更多,当然也可能是几百亿的大数字。一般这类数字统称为高精度数,高精度算法是用计算机对于超大数据的一种模拟加,减,乘,除,乘方,阶乘等运算。对于非常庞大的数字无法在计算机中正常存储。于是,将这个数字拆开成一位一位的,或者是四位四位的存储到一个数组中, 用一个数组去表示一个数字,这样这个数字就被称为是高精度数

高精度就是说参与运算的数据和运算结果的范围,超出标准数据类型能表示的数据大小范围的运算。此时如果要得到正确的计算结果,就不能依靠普通方法实现了,而要在普通运算原理的基础上,加以辅助算法来实现超大数据的计算。
例如:求两个 500 位的数据相乘的结果,这时就要用到高精度算法了。


二、高精度算法的实现

1、高精度加法(大整数相加)

大整数又称为高精度整数,其含义就是用基本数据类型无法存储其精度的整数。 大整数的存储使用数组即可。

 

思路:

先将大整数倒序存储,然后从左往右相加,这样才算是从低位往高位加,并判断是否有进位,加出来的数取余后尾插到要保存的vector中,这样求出来的数还是逆序的,但是主函数会从后往前读

 AC代码:

#include<iostream>
#include<string>
#include<vector>
using namespace std;

//1、高精度加法(大整数加法)
vector<int> add(vector<int>& A, vector<int>& B)
{
	//如果B更大,因为下面代码都是以第一个形参作为for结束条件,所以要让大的是第一个形参
	if (A.size() < B.size()) return add(B, A);

	vector<int> C;
	int t = 0; //用来判断是否进位
	//注意这里是逆序的数从前往后加的
	for (int i = 0; i < A.size(); ++i)
	{//for循环是以大的数来作为循环结束条件的
		t += A[i];//for循环以A为结束条件,这里不用格外判断
		if (i < B.size()) t += B[i];//因没以B为结束条件,故这里要格外判断是否可以加
		C.push_back(t % 10);//加出来的数要的是余数
		t /= 10; //判断是否有进位
	}
	if (t) C.push_back(t);//有可能最后加完还有进位

	//第二种写法
	//这种写法不用格外判断最后是否有进位
	//for (int i = 0, t = 0; i < A.size()||t; ++i)
	//{
	//	if (i < A.size()) t += A[i];//因为有t作为条件,故这里要格外判断
	//	if (i < B.size()) t += B[i];//因没以B为结束条件,故这里要格外判断是否可以加
	//	C.push_back(t % 10);//加出来的数要的是余数
	//	t /= 10; //判断是否有进位
	//}

	return C;
}

int main()
{
	string a, b;
	cin >> a >> b;
	vector<int> A, B;
	//把字符串逆序存入vector中,方便后续计算
	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 C = add(A, B);
	for (int i = C.size() - 1; i >= 0; --i) cout << C[i];
	cout << endl;

	return 0;
}

2、高精度减法(大整数减法)

思路:

和加法区别在于其一,减法是要借位而不是进位,其二,减法会导致有前导0存在。

什么是前导0?比如124-113,我们存的是421,311,相减时是4-3=1,2-1=1,1-1=0,然后尾插导致C为110,我们最后是逆着读的,即011,(但正常124-113=11),这里011肯定不对,多了一个前导0,故我们最后要把这个前导0去掉变成11,然后逆着读出来就对了

AC代码: 

#include<iostream>
#include<string>
#include<vector>
using namespace std;

//比较哪个数大,注意这里的数是从倒序存的,故后面的才是高位
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)
{//利用cmp函数比较,使大的数一定是A,与for循环代码相符

	vector<int> C;
	int t = 0;//判断借位
	for (int i = 0; i < A.size(); ++i)
	{
		t = A[i] - t;//每次都会减掉借位
		if (i < B.size()) t -= B[i];
		//关于(t+10)%10(t是减出来的数)
		//t若为正数(但<=9)其=t%10+10%10=t
		//t若为负数,正好可以借位+10然后取余数即可
		C.push_back((t + 10) % 10);
		if (t >= 0) t = 0;
		else t = 1; //<0肯定有借位了
	}
	//因为两个数相减会导致有多余的0出现,故去除前导0
    //size()>1是因为可能真的相减出现0,这种0不算前导0
	while (C.size() > 1 && C.back() == 0) C.pop_back();

	return C;
}

int main()
{
	string a, b;
	cin >> a >> b;
	vector<int> A, B;
	//把字符串逆序存入vector中,方便后续计算
	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');

	vector<int> C;
	if (cmp(A, B)) C = sub(A, B); //正数
	else cout << "-", C = sub(B, A); //负数

	for (int i = C.size() - 1; i >= 0; --i) cout << C[i];
	cout << endl;

	return 0;
}

3、高精度乘法(大整数*小整数)

思路: 

AC代码: 

#include<iostream>
#include<string>
#include<vector>
using namespace std;

vector<int> mul(vector<int>& A, int b)
{
	vector<int> C;
	for (int i = 0, t = 0; i < A.size() || t; ++i)
	{
		if (i < A.size()) t += A[i] * b;//加上t是因为上一次可能有乘出来的进位
		C.push_back(t % 10);
		t /= 10;//计算进位
	}
	//当b是0时,会出现前导0
	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');

	auto C = mul(A, b);

	for (int i = C.size() - 1; i >= 0; --i) cout << C[i];
	cout << endl;

	return 0;
}

4、高精度除法(大整数/小整数)

思路:

 

AC代码:

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;

vector<int> div(vector<int>& A, int b, int& r)
{
	vector<int> C;
	for (int i = A.size() - 1; i >= 0; --i)
	{
		r = r * 10 + A[i];
		C.push_back(r / b);
		r %= b; //计算余数
	}
	//逆置:因为我们是正常求,但最后是倒着读的,且便于去除前导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 = 0; //余数
	auto C = div(A, b, r);

	for (int i = C.size() - 1; i >= 0; --i) cout << C[i];
	cout << endl << r << endl;

	return 0;
}

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

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

相关文章

硬件寿命警告!Windows11在特定情况下对【固态硬盘】执行与【机械硬盘】相同的磁盘碎片整理。

首图&#xff0c;无图无真相 据我所知 此bug已持续约3个月。 此bug目前仍可以在Windows Feature Experience Pack 1000.25997.1000.0版本复现&#xff08;截至2023/11/21&#xff0c;最新的Windows预览金丝雀通道&#xff09; 如何复现 1 手动运行系统维护&#xff0c;点…

<C++> 模板-下

目录 前言 一、非类型模板参数 二、类模板的特化 1. 概念 2. 函数模板特化 3. 类模板特化 4. 全特化 5. 偏特化 5.1 特化部分参数 5.2 对某些类型的进一步限制 三、模板的分离编译 1. 概念 2. 分离编译 3. 解决方法 1. 显式实例化 2. 在一个文件内写声明和定义 四、模板总结 …

UE5、CesiumForUnreal实现加载GeoJson绘制盒体(Box)功能(StaticMesh方式)

文章目录 1.实现目标2.实现过程2.1 实现原理2.2 具体代码2.3 应用测试2.3.1 材质2.3.2 蓝图测试3.参考资料1.实现目标 与之前基于StaticMesh创建Polygon和Wall类似,本文通过读取本地GeoJson数据,在UE中以staticMeshComponent的形式绘制出盒体Box,支持Editor和Runtime模式,在…

HR人才测评,提高员工和岗位的适配度

作为中小企业领导&#xff0c;除了操心企业的经营管理&#xff0c;还得经常为内部运行做考虑。某个岗位总是缺少匹配的员工&#xff0c;而公司的员工如何进行岗位优化&#xff0c;这都是人资管理中经常遇到的难题&#xff0c;归根结底&#xff0c;是对人才评价的难题。 人才&a…

【PHY6222】simpleBLEPeripheral剖析

源码剖析 main.c main函数中所有使用extern引用外部的函数均无源码&#xff0c;具体细节不可知。 可以看到源码函数有以下几个&#xff1a; hal_rfphy_init&#xff1a; 相关参数&#xff1a; hal_init&#xff1a; jump_table.c 因为rom的code是不开源的&#xff0c;rom代…

ubuntu 安装 gparted

前提环境&#xff1a; 阿里云的源。 sudo apt update sudo apt upgrade sudo apt install gparted 搜索&#xff1a;

新能源充电桩工业4G路由器应用,推动绿色出行,响应环保理念

在智慧城市环保事业发展领域&#xff0c;新能源技术应用成熟&#xff0c;物联网技术越来越广泛&#xff0c;充电桩物联网成为了智慧城市建设的热门应用。充电桩作为新能源汽车的重要配套设施&#xff0c;对于节能减排和推动环保理念可持续发展具有重要意义。而工业4G路由器作为…

OpenLayers入门,OpenLayers6的WebGLPointsLayer图层样式运算符详解

专栏目录: OpenLayers入门教程汇总目录 前言 本章讲解使用OpenLayers6的WebGL图层显示大量点情况下,列举出所有WebGLPointsLayer图层所支持的所有样式运算符大全。 二、基于的OpenLayers版本 "ol": "^6.15.1"使用npm安装依赖npm install ol@6.15.1使…

Transformer——encoder

本文参考了b站的Eve的科学频道中的深入浅出解释Transformer原理和DASOU讲AI中的Transformer从零详解。 入浅出解释Transformer原理 Transformer从零详解 前言&#xff1a; 在自然语言识别中&#xff0c;之前讲过lstm&#xff0c;但是lstm有明显的缺陷&#xff0c;就是当文本过…

GNSS技术在灾害监测与应急响应中的关键作用

全球导航卫星系统&#xff08;GNSS&#xff09;技术在灾害监测与应急响应领域发挥着重要作用&#xff0c;为预防、监测和应对自然灾害提供了关键数据支持。本文将深入探讨GNSS技术在灾害监测与应急响应中的作用&#xff0c;并分析其对提高应对灾害能力的重要性。 一、GNSS在灾害…

78基于matlab的BiLSTM分类算法,输出迭代曲线,测试集和训练集分类结果和混淆矩阵

基于matlab的BiLSTM分类算法&#xff0c;输出迭代曲线&#xff0c;测试集和训练集分类结果和混淆矩阵&#xff0c;程序有详细注释&#xff0c;数据可更换自己的&#xff0c;程序已调通&#xff0c;可直接运行。

大模型的实践应用7-阿里的多版本通义千问Qwen大模型的快速应用与部署

大家好,我是微学AI,今天给大家介绍一下大模型的实践应用7-阿里的多版本通义千问Qwen大模型的快速应用与部署。阿里云开源了Qwen系列模型,即Qwen-7B和Qwen-14B,以及Qwen的聊天模型,即Qwen-7B-Chat和Qwen-14B-Chat。通义千问模型针对多达 3 万亿个 token 的多语言数据进行了…

轻量封装WebGPU渲染系统示例<37>- 多个局部点光源应用于非金属材质形成的效果(源码)

当前示例源码github地址: https://github.com/vilyLei/voxwebgpu/blob/feature/rendering/src/voxgpu/sample/BasePbrMaterialMultiLights.ts 当前示例运行效果: 此示例基于此渲染系统实现&#xff0c;当前示例TypeScript源码如下&#xff1a; export class BasePbrMaterial…

5.4 Windows驱动开发:内核通过PEB取进程参数

PEB结构(Process Envirorment Block Structure)其中文名是进程环境块信息&#xff0c;进程环境块内部包含了进程运行的详细参数信息&#xff0c;每一个进程在运行后都会存在一个特有的PEB结构&#xff0c;通过附加进程并遍历这段结构即可得到非常多的有用信息。 在应用层下&am…

SQL基础理论篇(九):存储过程

文章目录 简介存储过程的形式定义一个存储过程使用delimiter定义语句结束符存储过程中的三种参数类型流控制语句 存储过程的优缺点参考文献 简介 存储过程Stored Procedure&#xff0c;SQL中的另一个重要应用。 前面说的视图&#xff0c;只能勉强跟编程中的函数相似&#xff…

datagrip只导出表结构

话不多说&#xff0c;直接上教程。 datagrip版本&#xff1a;2022.3 第一步&#xff0c;连接数据库 第二步&#xff0c;右击数据库&#xff0c;复制即可

vivado产生报告阅读分析14-时序报告10

Vivado IDE 中的例外报告 “ Report Exceptions ”对话框 在 AMD Vivado ™ IDE 中 &#xff0c; 选择“ Reports ” → “ Timing ” → “ Report Exceptions ” &#xff08; 报告 > 时序 > 例外报告 &#xff09; 即可打开“Report Exceptions ”对话框。 从“…

做接口自动化遇到的20个难点,记录下我是如何解决的!

我是一名接口自动化测试工程师&#xff0c;在公司中负责接口自动化测试的设计和执行。在公司中&#xff0c;接口自动化测试非常重要&#xff0c;因为公司的业务场景非常复杂&#xff0c;需要保证接口的质量。在这篇文章中&#xff0c;我将分享我在公司中接口自动化测试遇到的20…

Java JSON字符串替换其中对应的值

代码&#xff1a; public static void main(String[] args) { // String theData crmScene.getData();String theData "[{\"type\":1,\"values\":[\"审批中\",\"未交付\"],\"name\":\"status\"}]"…

UE4 基础篇十四:自定义插件

文末有视频地址和git地址 一、概念 虚幻里插件都是用C++写的,C++包括.h文件和.cpp文件,.h头文件通常包含函数类型和函数声明,cpp文件包含这些类型和函数的实现, 你为项目编写的所有代码文件都必须位于模块中,模块就是硬盘里的一个文件夹,包含名为“Build.cs”的C#文件…