当前位置: 首页 > news >正文

大数计算(大数加法/大数乘法)

🐶博主主页:@ᰔᩚ. 一怀明月ꦿ 

❤️‍🔥专栏系列:线性代数,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

 🌸🌸🌸如果大家还有不懂或者建议都可以发在评论区,我们共同探讨,共同学习,共同进步。谢谢大家! 🌸🌸🌸   

相关文章:

大数计算(大数加法/大数乘法)

&#x1f436;博主主页&#xff1a;ᰔᩚ. 一怀明月ꦿ ❤️‍&#x1f525;专栏系列&#xff1a;线性代数&#xff0c;C初学者入门训练&#xff0c;题解C&#xff0c;C的使用文章&#xff0c;「初学」C &#x1f525;座右铭&#xff1a;“不要等到什么都没有了&#xff0c;才下…...

【腾讯云 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 费马平方和定理

&#x1f468;‍&#x1f3eb; Rikka with Square Numbers &#x1f9c0; 参考题解 &#x1f37b; 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配置项传递数据&#xff08;适用于父组件给子组件传递数据&#xff09; 父组件向子组件传递数据&#xff1a; 父组件代码&#xff1a;在子组件的标签中传递数据 <template><div><h2>学校名称&#xff1a;{{schoolName}}</h2><!-- 方…...

《2023年中国企业数字化转型发展白皮书》发布

导读 本报告主要采用市场调查、行业深度访谈、桌面研究等方法&#xff0c;并使用艾媒咨询旗下各大数据计算系统和相关计算模型。 对部分相关的公开信息进行筛选&#xff0c;通过对行业专家、相关企业与网民进行深度访谈&#xff0c;了解相关行业主要情况&#xff0c;获得相应…...

基于Python 简易实现接口测试自动化

目录 实现思路 统筹脚本 请求封装 日志封装 结果比对 结果邮件 用例获取及数据格式化 请求url转换 测试用例excel结构 测试报告 邮件接收结果 资料获取方法 实现思路 使用excel管理用例用例信息&#xff0c;requests模块发送http请求&#xff0c;实现了记录日志&…...

创建线程、线程的挂起与恢复、线程的优先级与终止线程

目录 一、创建线程 CreateThread函数&#xff1a; 下面是示例&#xff1a; ​编辑 ThreadProc函数解释&#xff1a; DWORD的本质是 unsigned long PVOID的本质是 void* 二、线程的终止 1.WaitForSingleObject()函数&#xff1a; 示例如下&#xff1a; 2.ExitThread()函…...

[保研/考研机试] KY180 堆栈的使用 吉林大学复试上机题 C++实现

题目链接&#xff1a; 堆栈的使用_牛客题霸_牛客网 描述 堆栈是一种基本的数据结构。堆栈具有两种基本操作方式&#xff0c;push 和 pop。其中 push一个值会将其压入栈顶&#xff0c;而 pop 则会将栈顶的值弹出。现在我们就来验证一下堆栈的使用。 输入描述&#xff1a; 对于…...

【AI理论学习】手把手推导扩散模型:Diffusion Models(DDPM)

手把手推导扩散模型&#xff1a;Diffusion Models&#xff08;DDPM&#xff09; DDPM理论回顾前置知识过程详解Forward ProcessReverse Process DDPM算法伪代码训练部分采样部分 总结一下 参考链接 在这篇博客文章中&#xff0c;我们将深入研究 去噪扩散概率模型(也称为 DDPM&…...

智能汽车 论坛收集

1.焉知汽车 焉知汽车 2.智能汽车俱乐部 智能汽车资源网 - 智能表面&#xff0c;智能内饰&#xff0c;新能源汽车&#xff0c;HMI&#xff0c;人车交互&#xff0c;智能车灯&#xff0c;车用材料 3.行业报告 发现报告 - 专业研报平台丨收录海量行业报告、券商研报丨免费分享…...

24届近5年南京航空航天大学自动化考研院校分析

今天给大家带来的是南京航空航天大学控制考研分析 满满干货&#xff5e;还不快快点赞收藏 一、南京航空航天大学 学校简介 南京航空航天大学创建于1952年10月&#xff0c;是新中国自己创办的第一批航空高等院校之一。1978年被国务院确定为全国重点大学&#xff1b;1981年经…...

Linux Day07

一、僵死进程 1.1僵死进程产生的原因 子进程先于父进程结束, 而父进程没有获取子进程退出码&#xff0c;释放子进程占用的资源&#xff0c;此时子进程将成为一个僵死进程。 在第一个框这里时父进程子进程都没有结束&#xff0c;显示其pid 父进程是2349&#xff0c;子进程是235…...

数字化管理,让MRO工业品更高效

MRO商品数字化是将MRO商品的采购、库存及记录过程进行数字化管理&#xff0c;以提高MRO商品的效率和可控性。MRO&#xff08;Maintenance, Repair and Operations&#xff09;一般用于维修、保养及日常运营工作中&#xff0c;包括五金工具、紧固件、精加工刀具、备品备件、切屑…...

layui中渲染table表格

页面布局 可直接根据文档要求去写 table 组件&#xff08;这个不重要&#xff09; <table lay-filter"SyDictTable" id"SyDictTable" lay-data"{id: SyDictTable}"></table>Js 重要的是去修改JS里面的东西&#xff0c;比如&#…...

2023-08-10LeetCode每日一题(下降路径最小和 II)

2023-08-10每日一题 一、题目编号 1289. 下降路径最小和 II二、题目链接 点击跳转到题目位置 三、题目描述 给你一个 n x n 整数矩阵 grid &#xff0c;请你返回 非零偏移下降路径 数字和的最小值。 非零偏移下降路径 定义为&#xff1a;从 grid 数组中的每一行选择一个数…...

网络基础2(HTTP,HTTPS,传输层协议详解)

再谈协议 在之前利用套接字进行通信的时候&#xff0c;我们都是利用 “字符串” 进行流式的发送接收&#xff0c;但是我们平常进行交流通信肯定不能只是简单的发送字符串。 比如我们用QQ进行聊天&#xff0c;我们不仅需要得到对方发送的消息&#xff0c;还要知道对方的昵称&…...

Java实现籍贯级联选择器

在工作中要求写一个籍贯的级联选择器&#xff0c;记录一下自己写这个级联选择器的过程&#xff0c;因为自己才刚开始工作&#xff0c;有很多地方都没有考虑的很清楚&#xff0c;希望各位大佬能给出建议。 一、需求 A:正常的23个省&#xff0c;籍贯由“省区/县/市”组成&#xf…...

每日一学——OSI参考模型

OSI参考模型&#xff08;Open Systems Interconnection Reference Model&#xff09;是国际标准化组织&#xff08;ISO&#xff09;制定的一个网络通信协议的概念框架。它将网络通信划分为七个层次&#xff0c;每个层次负责不同的功能和任务&#xff0c;从物理层到应用层依次为…...

虚幻5中Lumen提供哪些功能以及如何工作的

虚幻引擎 5 中的 Lumen 是一个完全动态的全局照明和反射系统。它可以在虚幻引擎 5 中使用&#xff0c;因此创作者无需自行设置。它是为下一代控制台和建筑可视化等高端可视化而设计的。那么它提供了哪些功能以及如何工作&#xff1f; 全局照明 当光离开光源时&#xff0c;它会…...

Linux C 语言 mosquitto 方式 MQTT 发布消息

1 说明 采用 mosquitto 库&#xff0c;实现对主题发布消息。 其中服务器有做限制&#xff0c;需要对应的 cilent id &#xff0c;cafile 、certfile 、keyfile 等配置 2 开发环境 采用ubuntu 直接编译调试 安装mosquitto 库 sudo apt install libmosquitto-dev sudo apt-ge…...

Java 语言特性(面试系列2)

一、SQL 基础 1. 复杂查询 &#xff08;1&#xff09;连接查询&#xff08;JOIN&#xff09; 内连接&#xff08;INNER JOIN&#xff09;&#xff1a;返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

微信小程序之bind和catch

这两个呢&#xff0c;都是绑定事件用的&#xff0c;具体使用有些小区别。 官方文档&#xff1a; 事件冒泡处理不同 bind&#xff1a;绑定的事件会向上冒泡&#xff0c;即触发当前组件的事件后&#xff0c;还会继续触发父组件的相同事件。例如&#xff0c;有一个子视图绑定了b…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法

树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作&#xff0c;无需更改相机配置。但是&#xff0c;一…...

React hook之useRef

React useRef 详解 useRef 是 React 提供的一个 Hook&#xff0c;用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途&#xff0c;下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

MODBUS TCP转CANopen 技术赋能高效协同作业

在现代工业自动化领域&#xff0c;MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步&#xff0c;这两种通讯协议也正在被逐步融合&#xff0c;形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容

目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法&#xff0c;当前调用一个医疗行业的AI识别算法后返回…...

均衡后的SNRSINR

本文主要摘自参考文献中的前两篇&#xff0c;相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程&#xff0c;其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt​ 根发送天线&#xff0c; n r n_r nr​ 根接收天线的 MIMO 系…...

重启Eureka集群中的节点,对已经注册的服务有什么影响

先看答案&#xff0c;如果正确地操作&#xff0c;重启Eureka集群中的节点&#xff0c;对已经注册的服务影响非常小&#xff0c;甚至可以做到无感知。 但如果操作不当&#xff0c;可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...

腾讯云V3签名

想要接入腾讯云的Api&#xff0c;必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口&#xff0c;但总是卡在签名这一步&#xff0c;最后放弃选择SDK&#xff0c;这次终于自己代码实现。 可能腾讯云翻新了接口文档&#xff0c;现在阅读起来&#xff0c;清晰了很多&…...