大数计算(大数加法/大数乘法)
🐶博主主页:@ᰔᩚ. 一怀明月ꦿ
❤️🔥专栏系列:线性代数,C初学者入门训练,题解C,C的使用文章,「初学」C++
🔥座右铭:“不要等到什么都没有了,才下定决心去做”
🚀🚀🚀大家觉不错的话,就恳求大家点点关注,点点小爱心,指点指点🚀🚀🚀
目录
概念
大数加法
加法原理
编程分析
大数乘法
乘法原理
编程分析
(1)累加法
(2)直接乘积法
效率对比
结果
概念
计算机发明的初衷就是解决以人类计算能力无法有效解决的问题,这类问题包括反复多次的复杂运算也包括天文级数字的运算,但就c语言的初步学习可以发现,不论是int还是float乃至更大的unsigned long long int和double形式的数据都是有极限的。一般形式的数据里最大的整型是unsigned long long int,极限为18446744073709551615,是10^19次方的数量级,就日常生活的问题可能足够了,但以计算机的计算能力而言远远不够。
例如64位下的一个整形为例,一个整形四个字节,32bit位,存储的最大数据为4294967296,然而4294967295只有10位,如果字符数组存储只需两个字节,而且数组长度可以非常大。所以用字符数组存储数据,模拟计算数据去解决天文级数字的运算等难题。
大数加法
加法原理
进行计算之前,我们先明白加法的原理
例如 12+9=21
2+9+0(余数)=11
余数:1
取模:1
1+1(余数)=2
余数:0
取模:2
所以等于21
转化为编程思想:
例如 12+9=21
str:string的对象,next:表示进位
next=0;
str:”"
2+9+next=11
next=1
str:”1”
1+0+next=2
next=0
str:”12”
最后逆置一下str,str:”21"
编程分析
string addStrings(string num1, string num2)//num1存储第一个数据,num2存储第二个数据 {int end1=num1.size()-1,end2=num2.size()-1;//这里我们获取每个数据的最后一位数的下标,因为我们进行计算,都是从最后一位数计算的int next=0;//表示的进位string str;//存储两个数据之和的对象while(end1>=0||end2>=0)//值得注意的是,我们对两个数据相加,是对每一个数据对应位相加,但如果一个数据min的位数少于另一位max数据,我们不能停止相加,只是max多余的位都加0而已,所以这里的循环结束的条件是,两个数据遍历完才停止。{//我们存储数据是用字符数组,计算数据还是以整形计算int x1=end1>=0?num1[end1]-'0':0;//x1就是获取一个数据end1下标的数据,之所以会减'0',在num存储的数据是字符,只要减'0'才是对应的整数。end1>=0?num1[end1]-'0':0如果num1数据遍历完了,就会让x1的值为0int x2=end2>=0?num2[end2]-'0':0;//x2就是获取一个数据end2下标的数据,之所以会减'0',在num存储的数据是字符,只要减'0'才是对应的整数。end2>=0?num2[end2]-'0':0如果num2数据遍历完了,就会让x2的值为0int ret=x1+x2+next;//计算两个数据对应位之和next=ret/10;//两个数据对应位之和大于等于10,就会产生进位ret=ret%10;//两个数据对应位之和小于10str+=ret+'0’;//存储两个数据对应位之和小于10的部分end1--,end2—;//让两个数据的下标往前移动}reverse(str.begin(),str.end());//因为str存储的数据是相反的,所以需要逆置一下,reverse是string类里的逆置函数if(next==1)//就是两个数据相加时,最后一位也可能产生进位,例如:98+3,str里只保存了01,而最高位的1还没有保存就跳出循环了,所以在这里,可以将进位头插在str中str.insert(0,1,'1’);//在str下标为0处插入1个’1'return str; }
大数乘法
乘法原理
进行计算之前,我们先明白乘法的原理
例如 25*12=300
5*2+0(余数)=10
取余:1
取模:0
2*2+1(余数)=5
取余:0
取模:5
个位乘积:50
5*1+(余数)=5
取余:0
取模:5
2*1+(余数)=2
取余:0
取模:2
十位乘积:25
总积:25*10+50=300
转化为编程思想:
例如 25*12=300
strN:string的对象,str:string的对象,next:表示进位
next=0
str=“”
strN=“0”
5*2+next=10
next=1
str=“0”
2*2+next=5
next=0
str=“05”
strN=strN+“50”
next=0
str=“”
5*1+next=5
next=0
str=“5”
2*1+next=2
next=0
str=“52”
strN=strN+”250”
strN=“300"
编程分析
(1)累加法
其实,乘法可以转换为加法,例如25*12,我们可以将25累加12次,这样也能达到乘法的效果。
缺陷:效率低
string multiply_1(string num1, string num2)//num1存储第一个数据,num2存储第二个数据 {string strN=num1;//strN时记录乘积总和的对象,我们将num2的数据传递strNint n=0;//n是存储的是num2整形的数字,例如num2=“123”,n=123for(int i=0,j=pow(10,num2.size()-1);i<num2.size();i++,j/=10)//这个循环就是转换过程{n+=(num2[i]-'0')*j;}n-=1;//因为我们开始在strN中存储了num2的数据,所以我们在家的过程需要少累加一次while(n—)//通过循环开始累加{//我们存储数据是用字符数组,计算数据还是以整形计算string str;//str存储的是一次累加的数据int end1=num1.size()-1,end2=strN.size()-1;//这里我们获取每个数据的最后一位数的下标,因为我们进行计算,都是从最后一位数计算的int next=0;//进位while(end1>=0||end2>=0){int x1=end1>=0?num1[end1]-'0':0;//x1就是获取一个数据end1下标的数据,之所以会减'0',在num存储的数据是字符,只要减'0'才是对应的整数。end1>=0?num1[end1]-'0':0如果num1数据遍历完了,就会让x1的值为0int x2=strN[end2]-'0';//x2就是获取一个数据end2下标的数据,之所以会减'0',在strN存储的数据是字符,只要减'0'才是对应的整数。int ret=x1+x2+next;//计算两个数据对应位之和next=ret/10;//两个数据对应位之和大于等于10,就会产生进位ret=ret%10;//两个数据对应位之和小于10str+=ret+'0';//存储两个数据对应位之和小于10的部分end1--,end2--;//让两个数据的下标往前移动}reverse(str.begin(),str.end());//因为str存储的数据是相反的,所以需要逆置一下,reverse是string类里的逆置函数if(next==1)//就是两个数据相加时,最后一位也可能产生进位,例如:98+3,str里只保存了01,而最高位的1还没有保存就跳出循环了,所以在这里,可以将进位头插在str中str.insert(0,1,'1');//在str下标为0处插入1个’1'strN=str;//将str的数据传递给strN}return strN; }(2)直接乘积法
直接通过,乘法的计算原理进行计算
string multiply(string num1, string num2)//num1存储第一个数据,num2存储第二个数据 {int end2=num2.size()-1;//这里我们获取每个数据的最后一位数的下标,因为我们进行计算,都是从最后一位数计算的string strN("0”);//strN是记录乘积总和的对象,初始值为’0'int flag=-1;//是一个标志while(end2>=0&&(num1[0]!='0'&&num2[0]!='0’))//只要遍历完num2中的数据就结束运算,还有如果num1和num2中只要有一个为’0'就结束运算{int end1=num1.size()-1;//这里我们获取每个数据的最后一位数的下标,因为我们进行计算,都是从最后一位数计算的string str;//记录每次num1中的数据和num2中每一位值的乘积int next=0;//进位int x2=num2[end2]-'0’;//x2就是获取一个数据end2下标的数据,之所以会减'0',在strN存储的数据是字符,只要减'0'才是对应的整数。while(end1>=0)//遍历num1中的数据{int x1=num1[end1]-'0';//x1就是获取一个数据end1下标的数据,之所以会减'0',在num存储的数据是字符,只要减'0'才是对应的整数。int ret=x1*x2+next;//计算num1每一位和num1每一位的乘积next=ret/10;//num1每一位和num1每一位的乘积大于10,就会产生进位ret=ret%10;//num1每一位和num1每一位的乘积小于10的值str+=ret+'0’;//存储num1每一位和num1每一位的乘积小于10的值end1—;//让num1数据的下标往前移动}flag++;//标志+1end2--;//让num2数据的下标往前移动reverse(str.begin(),str.end());//因为str存储的数据是相反的,所以需要逆置一下,reverse是string类里的逆置函数int count=flag;//传递标志的值while(count—)//num2每一位值和num1数据乘积等级是不同的,num1第一位是个位,第二位是位,第三位是千位…,所以str存储数据是应该加上对应数目的’0'{str+='0';}char ch=next+'0';if(next!=0)//就是num2每一位值和num1数据乘积时,最后一位也可能产生进位,例如:98*3,str里只保存了94,而最高位的2还没有保存就跳出循环了,所以在这里,可以将进位头插在str中str.insert(0,1,ch);strN=addStrings(strN, str);//将num2每一位值和num1数据乘积累加给strN,addStrings是我们前面提到的大数加法}return strN; }效率对比
同时计算999999*999999,看所需要的时间
#include<iostream> #include<cmath> using namespace std; string multiply_1(string num1, string num2) {string strN=num1;int n=0;for(int i=0,j=pow(10,num2.size()-1);i<num2.size();i++,j/=10){n+=(num2[i]-'0')*j;}n-=1;while(n--){string str;int end1=num1.size()-1,end2=strN.size()-1;int next=0;while(end1>=0||end2>=0){int x1=end1>=0?num1[end1]-'0':0;int x2=strN[end2]-'0';int ret=x1+x2+next;next=ret/10;ret=ret%10;str+=ret+'0';end1--,end2--;}reverse(str.begin(),str.end());if(next==1)str.insert(0,1,'1');strN=str;}return strN; } //25 // 3 //next=0 //5*3+next=15 //next=1 //str:5 //2*3+next=7 //str:57 //75 string addStrings(string num1, string num2) {int end1=num1.size()-1,end2=num2.size()-1;int next=0;string str;while(end1>=0||end2>=0){int x1=end1>=0?num1[end1]-'0':0;int x2=end2>=0?num2[end2]-'0':0;int ret=x1+x2+next;next=ret/10;ret=ret%10;str+=ret+'0';end1--,end2--;}reverse(str.begin(),str.end());if(next==1)str.insert(0,1,'1');return str; } string multiply(string num1, string num2) {int end2=num2.size()-1;string strN("0");int flag=-1;while(end2>=0&&(num1[0]!='0'&&num2[0]!='0')){int end1=num1.size()-1;string str;int next=0;int x2=num2[end2]-'0';while(end1>=0){int x1=num1[end1]-'0';int ret=x1*x2+next;next=ret/10;ret=ret%10;str+=ret+'0';end1--;}flag++;end2--;reverse(str.begin(),str.end());int count=flag;while(count--){str+='0';}char ch=next+'0';if(next!=0)str.insert(0,1,ch);strN=addStrings(strN, str);}return strN; } int main() {string s1,s2;cin>>s1>>s2;size_t begin_1=clock();cout<<"累加法的值:"<<multiply_1(s1, s2)<<endl;size_t end_1=clock();cout<<"累加法的时间:"<<end_1-begin_1<<"10^-3ms"<<endl;size_t begin_2=clock();cout<<"直接乘积法的值:"<<multiply(s1, s2)<<endl;size_t end_2=clock();cout<<"直接乘积法的时间:"<<end_2-begin_2<<"10^-3ms"<<endl;return 0; }结果
结果:
999999 999999
累加法的值:999998000001
累加法的时间:51161310^-3ms
直接乘积法的值:999998000001
直接乘积法的时间:1210^-3ms
🌸🌸🌸如果大家还有不懂或者建议都可以发在评论区,我们共同探讨,共同学习,共同进步。谢谢大家! 🌸🌸🌸
相关文章:
大数计算(大数加法/大数乘法)
🐶博主主页:ᰔᩚ. 一怀明月ꦿ ❤️🔥专栏系列:线性代数,C初学者入门训练,题解C,C的使用文章,「初学」C 🔥座右铭:“不要等到什么都没有了,才下…...
【腾讯云 Cloud Studio 实战训练营】基于Cloud Studio构建React完成点餐H5页面
前言 【腾讯云 Cloud Studio 实战训练营】基于Cloud Studio 构建React完成点餐H5页面一、Cloud Studio介绍1.1 Cloud Studio 是什么1.2 相关链接1.3 登录注册 二、实战练习2.1 初始化工作空间2.2 开发一个简版的点餐系统页面1. 安装 antd-mobile2. 安装 less 和 less-loader3. …...
杭电多校 Rikka with Square Numbers 费马平方和定理
👨🏫 Rikka with Square Numbers 🧀 参考题解 🍻 AC code import java.util.Scanner;public class Main {static boolean isSqu(int x){int t (int) Math.sqrt(x);return t * t x;}public static void main(String[] args…...
跟禹神VUE——组件间的通信方式(props配置项、组件间自定义事件、全局事件总线、消息订阅与发布、VUEX)
一、通过props配置项传递数据(适用于父组件给子组件传递数据) 父组件向子组件传递数据: 父组件代码:在子组件的标签中传递数据 <template><div><h2>学校名称:{{schoolName}}</h2><!-- 方…...
《2023年中国企业数字化转型发展白皮书》发布
导读 本报告主要采用市场调查、行业深度访谈、桌面研究等方法,并使用艾媒咨询旗下各大数据计算系统和相关计算模型。 对部分相关的公开信息进行筛选,通过对行业专家、相关企业与网民进行深度访谈,了解相关行业主要情况,获得相应…...
基于Python 简易实现接口测试自动化
目录 实现思路 统筹脚本 请求封装 日志封装 结果比对 结果邮件 用例获取及数据格式化 请求url转换 测试用例excel结构 测试报告 邮件接收结果 资料获取方法 实现思路 使用excel管理用例用例信息,requests模块发送http请求,实现了记录日志&…...
创建线程、线程的挂起与恢复、线程的优先级与终止线程
目录 一、创建线程 CreateThread函数: 下面是示例: 编辑 ThreadProc函数解释: DWORD的本质是 unsigned long PVOID的本质是 void* 二、线程的终止 1.WaitForSingleObject()函数: 示例如下: 2.ExitThread()函…...
[保研/考研机试] KY180 堆栈的使用 吉林大学复试上机题 C++实现
题目链接: 堆栈的使用_牛客题霸_牛客网 描述 堆栈是一种基本的数据结构。堆栈具有两种基本操作方式,push 和 pop。其中 push一个值会将其压入栈顶,而 pop 则会将栈顶的值弹出。现在我们就来验证一下堆栈的使用。 输入描述: 对于…...
【AI理论学习】手把手推导扩散模型:Diffusion Models(DDPM)
手把手推导扩散模型:Diffusion Models(DDPM) DDPM理论回顾前置知识过程详解Forward ProcessReverse Process DDPM算法伪代码训练部分采样部分 总结一下 参考链接 在这篇博客文章中,我们将深入研究 去噪扩散概率模型(也称为 DDPM&…...
智能汽车 论坛收集
1.焉知汽车 焉知汽车 2.智能汽车俱乐部 智能汽车资源网 - 智能表面,智能内饰,新能源汽车,HMI,人车交互,智能车灯,车用材料 3.行业报告 发现报告 - 专业研报平台丨收录海量行业报告、券商研报丨免费分享…...
24届近5年南京航空航天大学自动化考研院校分析
今天给大家带来的是南京航空航天大学控制考研分析 满满干货~还不快快点赞收藏 一、南京航空航天大学 学校简介 南京航空航天大学创建于1952年10月,是新中国自己创办的第一批航空高等院校之一。1978年被国务院确定为全国重点大学;1981年经…...
Linux Day07
一、僵死进程 1.1僵死进程产生的原因 子进程先于父进程结束, 而父进程没有获取子进程退出码,释放子进程占用的资源,此时子进程将成为一个僵死进程。 在第一个框这里时父进程子进程都没有结束,显示其pid 父进程是2349,子进程是235…...
数字化管理,让MRO工业品更高效
MRO商品数字化是将MRO商品的采购、库存及记录过程进行数字化管理,以提高MRO商品的效率和可控性。MRO(Maintenance, Repair and Operations)一般用于维修、保养及日常运营工作中,包括五金工具、紧固件、精加工刀具、备品备件、切屑…...
layui中渲染table表格
页面布局 可直接根据文档要求去写 table 组件(这个不重要) <table lay-filter"SyDictTable" id"SyDictTable" lay-data"{id: SyDictTable}"></table>Js 重要的是去修改JS里面的东西,比如&#…...
2023-08-10LeetCode每日一题(下降路径最小和 II)
2023-08-10每日一题 一、题目编号 1289. 下降路径最小和 II二、题目链接 点击跳转到题目位置 三、题目描述 给你一个 n x n 整数矩阵 grid ,请你返回 非零偏移下降路径 数字和的最小值。 非零偏移下降路径 定义为:从 grid 数组中的每一行选择一个数…...
网络基础2(HTTP,HTTPS,传输层协议详解)
再谈协议 在之前利用套接字进行通信的时候,我们都是利用 “字符串” 进行流式的发送接收,但是我们平常进行交流通信肯定不能只是简单的发送字符串。 比如我们用QQ进行聊天,我们不仅需要得到对方发送的消息,还要知道对方的昵称&…...
Java实现籍贯级联选择器
在工作中要求写一个籍贯的级联选择器,记录一下自己写这个级联选择器的过程,因为自己才刚开始工作,有很多地方都没有考虑的很清楚,希望各位大佬能给出建议。 一、需求 A:正常的23个省,籍贯由“省区/县/市”组成…...
每日一学——OSI参考模型
OSI参考模型(Open Systems Interconnection Reference Model)是国际标准化组织(ISO)制定的一个网络通信协议的概念框架。它将网络通信划分为七个层次,每个层次负责不同的功能和任务,从物理层到应用层依次为…...
虚幻5中Lumen提供哪些功能以及如何工作的
虚幻引擎 5 中的 Lumen 是一个完全动态的全局照明和反射系统。它可以在虚幻引擎 5 中使用,因此创作者无需自行设置。它是为下一代控制台和建筑可视化等高端可视化而设计的。那么它提供了哪些功能以及如何工作? 全局照明 当光离开光源时,它会…...
Linux C 语言 mosquitto 方式 MQTT 发布消息
1 说明 采用 mosquitto 库,实现对主题发布消息。 其中服务器有做限制,需要对应的 cilent id ,cafile 、certfile 、keyfile 等配置 2 开发环境 采用ubuntu 直接编译调试 安装mosquitto 库 sudo apt install libmosquitto-dev sudo apt-ge…...
黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门 的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...
【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)
要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况,可以通过以下几种方式模拟或触发: 1. 增加CPU负载 运行大量计算密集型任务,例如: 使用多线程循环执行复杂计算(如数学运算、加密解密等)。运行图…...
laravel8+vue3.0+element-plus搭建方法
创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...
NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合
在汽车智能化的汹涌浪潮中,车辆不再仅仅是传统的交通工具,而是逐步演变为高度智能的移动终端。这一转变的核心支撑,来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒(T-Box)方案:NXP S32K146 与…...
【Veristand】Veristand环境安装教程-Linux RT / Windows
首先声明,此教程是针对Simulink编译模型并导入Veristand中编写的,同时需要注意的是老用户编译可能用的是Veristand Model Framework,那个是历史版本,且NI不会再维护,新版本编译支持为VeriStand Model Generation Suppo…...
GraphQL 实战篇:Apollo Client 配置与缓存
GraphQL 实战篇:Apollo Client 配置与缓存 上一篇:GraphQL 入门篇:基础查询语法 依旧和上一篇的笔记一样,主实操,没啥过多的细节讲解,代码具体在: https://github.com/GoldenaArcher/graphql…...
Tauri2学习笔记
教程地址:https://www.bilibili.com/video/BV1Ca411N7mF?spm_id_from333.788.player.switch&vd_source707ec8983cc32e6e065d5496a7f79ee6 官方指引:https://tauri.app/zh-cn/start/ 目前Tauri2的教程视频不多,我按照Tauri1的教程来学习&…...
