8-高精度计算(加法)

2023-11-06

我们知道,在C语言和C++中对于所能存储的数值的最大值是有明确的上限的。但是我们有时候会需要去计算一些数值比较大的数字:例如位数为1000、10000的数字的加减运算,这时候我们就需要使用新的运算方法了。

这里引入高精度的大数据计算,它可以用计算位数很大例如10^{6}的数字。它的主要思想是利用数组进行存储大数的位数,并且利用计算规则的特点来进行计算,下面我们来看看加法。

首先是大数据的处理过程,我们一般long类型变量如果存不下的数据,我们考虑用一个数组或者vector类型的容器来存储。例如数字1598,我们可以用一个数组将其倒过来存储,arr[0]先存储个位,然后后面位数依次存进去(如下图下方图)。这样存有个好处,因为我们做加法运算时有可能会最大位向前进一位,如果此时我们选择arr[0]为最大位,那么我们进一就需要将整个数组向后镦一位(如下图上方图)。

了解完存储大数字的方式,接下来我们先来回忆一下加法的运算过程:例如我们有两个数组A,B,C,它们存储大数a,b的每个位上的数据,C为存储结果各个位数值的数组。然后我们先从两个数组对应的个位算起,将个位数字计算完后,看其是否需要向十位进位,以此类推计算。因为还要考虑进位问题,所以我们索性定义C每一位都是(A[i]+B[i]+t)%10,这里的t是前一位向本位进的位数。个位是t就是0就可以。例如下面的式子:A={9,3,1},B={7,3}。C[0]=(A[0]+B[0]+0)%10=16%10=6;C[1]=(A[1]+B[1]+1)%10=7%10=7;C[2]=(A[2]+0)%10=1%10=1。所以C为{6,7,1}。

按照这个思路,我们可以写出大数加法的代码,这里为了方便使用了容器vector:

整体代码分为两段:第一段是处理数据,第二段是大数计算。

先来看处理数据:我们用的是string类型的变量接收数据,所以我们要想换成vector容器存储每一个位,就需要将字符串中每一个数字转换为一个int类型的数据存进去A/B容器中。数字字符和数字有一个对应关系:x(char类型)-'0' = x(int类型)。这样就能获得一个存储着大数据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');

接下来就是核心的大数计算的部分了:

我们将两个需要进行加运算的容器传进函数中,然后用一个循环将两容器的每一位相加。举个例子:两个数字相加:120和3,它们结果是123,这里的120中的1和2没有运算,因为3只需和120中的个位运算。同理,两个数相加要么是两个数刚好相等,或者一方比另一方位数高,此时加法停止的条件就是位数高的那个数字的最高位计算完毕。所以循环的结束条件是当加到A、B中最大的那位,此时加法停止。所以有下面的停止判断条件。

 i < A.size() || i < B.size()

 然后我们来看里面的两个if,这两个if是我们不确定A还是B的位数高,所以让位数低的位数计算完后先停止运算,而位数高的继续计算。然后将加得的数据对十取模来获得A、B对应位的结果,赋给C,最后再将t除10获得进位。最后的if(t)是判断两个数相加是否需要增位,判断最后运算完是否需要向下一次进1,也就是判断t是否为1。是就加1,不是不处理。

vector<int> add(vector<int>& A, vector<int>& B)
{
	vector<int> C;
	int t = 0;
	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];
		C.push_back(t % 10);
		t = t / 10;
	}
	if (t) C.push_back(1);
	return C;
}

总体代码: 

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


vector<int> add(vector<int>& A, vector<int>& B)
{
	vector<int> C;
	int t = 0;
	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];
		C.push_back(t % 10);
		t = t / 10;
	}
	if (t) C.push_back(1);
	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');
	auto C = add(A, B);

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

	return 0;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

8-高精度计算(加法) 的相关文章

  • C#动态支持吗?

    看完之后这个帖子 https stackoverflow com questions 2674906 when should one use dynamic keyword in c sharp 4 0k和链接 我还有 2 个问题 问题 1
  • 如何创建可以像 UserControl 一样编辑的 TabPage 子类?

    我想创建一个包含一些控件的 TabPage 子类 并且我想通过设计器来控制这些控件的布局和属性 但是 如果我在设计器中打开子类 我将无法像在 UserControl 上那样定位它们 我不想创建一个带有 UserControl 实例的 Tab
  • 32 位应用程序的特征最大矩阵大小

    所以 我正在寻找Eigen http eigen tuxfamily org index php title Main Page当我尝试声明大于 10000x10000 的矩阵时 包崩溃 我需要声明一个像这样的矩阵 可靠地大约有 13000
  • 从 MVC 迁移到 ASP.NET Core 3.1 中的端点路由时,具有角色的 AuthorizeAttribute 不起作用

    我正在尝试将我的项目从 UseMVC asp net core 2 2 兼容样式 升级到 UseEndpoint Routing 并且我的所有请求都被重定向到我的验证失败页面 它与声明有关 如果我删除 Authorize Roles Adm
  • 构造函数中显式关键字的使用

    我试图了解 C 中显式关键字的用法 并查看了这个问题C 中的explicit关键字是什么意思 https stackoverflow com questions 121162 但是 那里列出的示例 实际上是前两个答案 对于用法并不是很清楚
  • C++ 异步线程同时运行

    我是 C 11 中线程的新手 我有两个线程 我想让它们同时启动 我可以想到两种方法 如下 然而 似乎它们都没有按照我的预期工作 他们在启动另一个线程之前启动一个线程 任何提示将不胜感激 另一个问题是我正在研究线程队列 所以我会有两个消费者和
  • 如何配置 WebService 返回 ArrayList 而不是 Array?

    我有一个在 jax ws 上实现的 java Web 服务 此 Web 服务返回用户的通用列表 它运行得很好 Stateless name AdminToolSessionEJB RemoteBinding jndiBinding Admi
  • 访问者和模板化虚拟方法

    在一个典型的实现中Visitor模式 该类必须考虑基类的所有变体 后代 在许多情况下 访问者中的相同方法内容应用于不同的方法 在这种情况下 模板化的虚拟方法是理想的选择 但目前这是不允许的 那么 模板化方法可以用来解析父类的虚方法吗 鉴于
  • C 语言中 =+(等于加)是什么意思?

    我碰到 与标准相反 今天在一些 C 代码中 我不太确定这里发生了什么 我在文档中也找不到它 In ancientC 版本 相当于 它的残余物与最早的恐龙骨头一起被发现 例如 B 引入了广义赋值运算符 使用x y to add y to x
  • 即使手动设置显示环境变量后,WSL Ubuntu 也会显示“错误:无法打开显示”

    我在 WSL Ubuntu 上使用 g 我使用 git 克隆了 GLFW 存储库 使用了ccmake命令配置并生成二进制文件 然后使用make在 build 目录中最终创建 a文件 我安装了所有OpenGL相关的库 usr ld 我不记得我
  • 为什么我不应该对不是由 malloc() 分配的变量调用 free() ?

    我在某处读到 使用它是灾难性的free删除不是通过调用创建的对象malloc 这是真的 为什么 这是未定义的行为 永远不要尝试它 让我们看看当您尝试时会发生什么free 自动变量 堆管理器必须推断出如何获取内存块的所有权 为此 它要么必须使
  • 将构建日期放入“关于”框中

    我有一个带有 关于 框的 C WinForms 应用程序 我使用以下方法将版本号放入 关于 框中 FileVersionInfo GetVersionInfo Assembly GetExecutingAssembly Location F
  • 获取 2 个数据集 c# 中的差异

    我正在编写一个简短的算法 它必须比较两个数据集 以便可以进一步处理两者之间的差异 我尝试通过合并这两个数据集并将结果更改放入新的数据集来实现此目标 我的方法如下所示 private DataSet ComputateDiff DataSet
  • g++ 对于看似不相关的变量“警告:迭代...调用未定义的行为”

    考虑以下代码strange cpp include
  • 将代码拆分为标头/源文件

    我从 Asio 的示例页面中获取了以下代码 class tcp connection public boost enable shared from this
  • 在类的所有方法之前运行一个方法

    在 C 3 或 4 中可以做到这一点吗 也许有一些反思 class Magic RunBeforeAll public void BaseMethod runs BaseMethod before being executed public
  • 当前的 x86 架构是否支持非临时加载(来自“正常”内存)?

    我知道有关此主题的多个问题 但是 我没有看到任何明确的答案或任何基准测量 因此 我创建了一个处理两个整数数组的简单程序 第一个数组a非常大 64 MB 第二个数组b很小 无法放入 L1 缓存 程序迭代a并将其元素添加到相应的元素中b在模块化
  • 为什么拆箱枚举会产生奇怪的结果?

    考虑以下 Object box 5 int int int box int 5 int nullableInt box as int nullableInt 5 StringComparison enum StringComparison
  • 剪贴板在 .NET 3.5 和 4 中的行为有所不同,但为什么呢?

    我们最近将一个非常大的项目从 NET Framework 3 5 升级到 4 最初一切似乎都工作正常 但现在复制粘贴操作开始出现错误 我已经成功制作了一个小型的可复制应用程序 它显示了 NET 3 5 和 4 中的不同行为 我还找到了一种解
  • WinRT 定时注销

    我正在开发一个 WinRT 应用程序 要求之一是应用程序应具有 定时注销 功能 这意味着在任何屏幕上 如果应用程序空闲了 10 分钟 应用程序应该注销并导航回主屏幕 显然 执行此操作的强力方法是在每个页面的每个网格上连接指针按下事件 并在触

随机推荐

  • 什么是企业用户画像,怎么构建企业用户画像

    企业画像 简单说 企业给人的印象 可以跟自然人的用户画像相类比 这其实是IT行业的一种叫法 在金融行业 一般叫做 尽职调查报告 当然 尽职调查报告只需要尽职 不需要说的太具体或者太难看 什么是企业用户画像 企业用户画像与个人用户画像有很大区
  • 反射/存储/DOM型XSS攻击原理及攻击流程详解

    文章目录 XSS漏洞原理 1 XSS分类 1 1 攻击流程 2 存储型XSS 2 1 攻击流程 3 DOM型XSS 3 1 攻击流程 XSS修复 XSS漏洞原理 XSS 跨站脚本攻击 是一种常见的 Web 安全漏洞 其允许攻击者在恶意用户的
  • 新版caffe添加自己的层(目前只学会添加,我想要添加的loss还没能实现)

    今天实现了在caffe框架中加入一个层 完成欧式距离的任务 之所以这样 是因为还没有实现自己想要的loss 只是试着学者 看能不能把添加层的流程顺下来 最后实现了 一 总体框架 1 在 src caffe proto caffe proto
  • SpringCache的介绍和使用

    1 简介 1 Spring 从 3 1 开始定义了 org springframework cache Cache和 org springframework cache CacheManager 接口来统一不同的缓存技术 并支持使用 JCa
  • 六、IP地址子网划分与VLAN

    一 IP地址的五大分类 概念 IP地址相当于人的身份证 用于在TCP IP通信协议中标记每台计算机的地址 通常用于十进制来表示 如192 168 1 100 但是在计算机内部 IP地址是一个32位的二进制数值 如11000000 10101
  • [转载]Chrome 与 Chrome OS 各版本下载集合

    Chrome OS 下载 由 Hexxeh提供的第三方编译版本 Chrome OS USB 镜像 点击这里 Chrome OS WMware 镜像 点击这里 Chrome OS Vanilla USB VMWare VirtualBox 点
  • 树的遍历-深度优先遍历和广度优先遍历

    深度优先遍历类似于树的先序遍历 假设给定初态是图中所有顶点均未被访问过 从图中某一顶点vi出发遍历图中的定义如下 首先访问出发点vi 并将其访问标志置为1 然后 从vi出发点依次搜索vi的每个邻接点vj 如vj未被访问过 则以vj为新的出发
  • 函数模板和类模板的实例化和具体化

    一 函数模板 1 显示实例化 explicit instantiation 和显示具体化 explicit specialization 的区别 1 形式上 显示实例化 template void Swap
  • estimate函数是什么?

    estimate 函数是用来估计参数值的函数 它通常用于统计学和机器学习中 用来求出一组样本数据的模型参数的最优解
  • VS2008/VS2010安装时提示VC++9.0 Runtime安装失败问题的解决方法

    查了一下 有以下几种解决方法 1 http blog csdn net zlqqhs article details 8821608 2 https dotblogs com tw johnny archive 2010 07 16 165
  • 矩阵向量求导(Matrix calculus)

    原文地址 注 不要把它和几何运算或者是向量运算混淆 前言 在数学中 矩阵微积分是进行多变量微积分的一种特殊符号 特别是在矩阵的空间上 它将关于许多变量的单个函数的各种偏导数和 或关于单个变量的多变量函数的偏导数收集到可以被视为单个实体的向量
  • linux从EMMC启动或TFTP启动的UBOOT参数

    从EMMC启动内核及设备树 setenv bootargs console ttymxc0 115200 root dev mmcblk1p2 rootwait rw setenv bootcmd mmc dev 1 fatload mmc
  • java-logback记录日志到指定文件并且压缩保存日志

    yml配置文件中加入如下配置 logging config classpath logback spring xml 项目根目录下的xml配置文件 level root info 全局日志的级别 file name mes log 输出日志
  • nvm 在 Windows 上的使用

    NVM Node Version Manager 是一个用于管理和切换多个 Node js 版本的工具 它允许你在同一台机器上同时安装和使用不同版本的 Node js 而无需手动安装和卸载 之前都是只安装一个版本的 node js 该更新时
  • 2021年字节跳动、阿里等大厂最全Android面试题,已开源

    前言 对于字节跳动的二面三面而言 Framework MVP架构 HashMap原理 性能优化 Flutter 源码分析等问题都成高频问点 然而很多的朋友在面试时却答不上或者答不全 今天在这分享下这些问点的视频解析给大家 希望对有需要的朋友
  • 一文教会你如何用 Python 分割合并大文件

    有时候 我们需要把一个大文件发送给别人 但是限于传输通道的限制 比如邮箱附件大小的限制 或者网络状况不太好 需要将大文件分割成小文件 分多次发送 接收端再对这些小文件进行合并 今天就来分享一下用 Python 分割合并大文件的方法 思路及实
  • 2017版VisualStudio asp.net利用ZXing生成条形码、二维码

    2017版VisualStudio asp net利用ZXing生成条形码 二维码 一 在asp net项目中添加ZXing 1 右击项目 管理NuGet程序包 2 搜索ZXing 下载ZXing net并安装即可 二 生成条形码 1 页面
  • Arch Linux 安装(痛苦版)

    我已经用了两年的Linux FreeBSD 平时都是硬盘安装 除了BSD有点阻碍 linux不在话下 但是Arch Linux让我感到无助 虽然最后是用光驱安装成功 为什么要装archLinux 我的二手笔记本 CPU P3 700 RAM
  • Test Driven Development感悟

    编程的思想有面向过程编程 面向对象编程 面向接口编程 面向接口编程是现在很多公司在使用的 面向接口效率更好 而且使得业务代码更加简洁易调试 面向对象的方法使得代码会多出很多接口 可以为以后的使用留接口 但是开发效率不高 面向过程写代码 可以
  • 8-高精度计算(加法)

    我们知道 在C语言和C 中对于所能存储的数值的最大值是有明确的上限的 但是我们有时候会需要去计算一些数值比较大的数字 例如位数为1000 10000的数字的加减运算 这时候我们就需要使用新的运算方法了 这里引入高精度的大数据计算 它可以用计