高精度加减乘除小数详解
高精度 简介众所周知,在计算机中,每个数据类型都是有存储上限的,
2023-08-15众所周知,在计算机中,每个数据类型都是有存储上限的,那么当数字特别大时应该怎么办呢?这时高精度就产生了。高精度的主要思想就是模拟手算,然后将结果存储到数组中去,相同的,小数也有精度问题,也可以使用相同的思路
存储这里使用vector
来进行存储,因为这样不需要去管结果有多少位,直接使用push_back()
函数就行了,虽然和数组比起来会慢一些,不过差别也仅仅是常数而已
输入:定义一个字符串,然后将字符串的每位转数字存储起来就行了
(资料图片仅供参考)
string a; vector A; cin>>a;for(int i=a.size()-1;i>=0;i--) A.push_back(a[i]-"0");
输出:请注意,输入的时候我是反过来的,这样做是为了添加元素比较方便,那么输出的时候也要注意倒着输出
for (int i = C.size() - 1; i >= 0; i--) printf("%d", C[i]);
高精度加法上文中已经提到,在进行高精度运算是模拟手算的,那么接下来就来回忆一下,我们是怎么手动做加法的
图为用竖式做加法的示例,我们可以发现主要组成部分有两个加数、结果、还有进位,于是我们的变量就可以呼之欲出了
vector A; vector B; vector C; int t;
然后我们再使用循环遍历(从0开始)来进行计算,循环位数较大的那个加数的每一位,然后加到 \(t\) 里面就行了
那么 \(C_i\) 就等于 \(A_i+B_i\) 再 \(mod~10\),进位 \(t\) 就等于 \((A_i+B_i)/10\)
注意在循环完之后,如果 \(t\neq 0\) 的话,还要加上一位
代码模板#include #include #include using namespace std;vector add(vector& A,vector& B){vector C; int t=0;for(int i=0;i>a;cin>>b;vector A;vector 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");vector C=add(A,B);for(int i=C.size()-1;i>=0;i--) cout<
高精度减法不带负数首先,先回忆一下我们是怎么用竖式进行减法的
与加法不同,我们在列减法的竖式时会把大数放在上面,小数放在下面,因为减法涉及到借位的问题
所以说在计算机计算的时候,我们要先判断 \(A\) 是否 \(\geq B\),如果 \(
那么因为数字特别大,所以我们也需要手写一个比较函数,那么我们是怎么比较两个数的呢?
先比较哪个位数大,位数多的大,如果位数一样,那么分别比较每一位
bool cmp(vector& A, vector& 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;}
类似加法,变量分别为被减数,减数,结果,借位
使用循环遍历(从0开始)被减数的每一位
借位 \(t\) = \(A_i-(B_i)-t\),如果说最终结果小于0,就要借一位,将 \(t+10\) 最后再 \(mod~10\) 便是 \(C_i\)
如果借位了 \(t=1\) 否则 \(t=0\)
注意:为了方便,我们直接不管结果是否小于0,每次都加10,因为如果结果不小于0的话 \(+10\) \(mod~10\) 就抵消了对结果不影响
最后还要去除前导0
while (C.size() > 1 && C.back() == 0){C.pop_back();}
代码模板#include #include #include using namespace std;bool cmp(vector& A,vector& 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 sub(vector& A,vector& B){int t=0;vector C;for(int i=0;i1&&C.back()==0) C.pop_back();return C;}int main(){string a,b;vector A,B;cin>>a;cin>>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");if(cmp(A,B)) {vector C=sub(A,B);for(int i=C.size()-1;i>=0;i--) cout< C=sub(B,A);cout<<"-";for(int i=C.size()-1;i>=0;i--) cout<
带有负数自然数 \(A\) 减负数 \(B\) 等于 $A+\vert B\vert $负数 \(A\) 减自然数 \(B\) 等于 \(-(\vert A \vert+B)\)自然数 \(A\) 减负数 \(B\) 等于 \(\vert A\vert+B\)负数 \(A\) 减负数 \(B\) 当 \(\vert A\vert\leq\vert B\vert\) 时,等于\(\vert B\vert -\vert A\vert\) 当 \(\vert A \vert>\vert B\vert\) 时,等于 \(-(\vert A\vert-\vert B\vert)\)代码模板#include #include #include using namespace std;bool cmp(vector& A,vector& 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;}bool cmp1(vector& A,vector& 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 false;}vector add(vectorA,vectorB){vector C; int t=0;for(int i=0;i sub(vector& A,vector& B){int t=0;vector C;for(int i=0;i1&&C.back()==0) C.pop_back();return C;}int main(){string a,b;vector A,B;cin>>a;cin>>b; if(a[0]!="-"&&b[0]!="-") { 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"); if(cmp(A,B)) { vector C=sub(A,B); for(int i=C.size()-1;i>=0;i--) cout< C=sub(B,A); cout<<"-"; for(int i=C.size()-1;i>=0;i--) cout<=1;i--) A.push_back(a[i]-"0"); for(int i=b.size()-1;i>=0;i--) B.push_back(b[i]-"0"); vector C=add(A,B); cout<<"-"; for(int i=C.size()-1;i>=0;i--) cout<=0;i--) A.push_back(a[i]-"0"); for(int i=b.size()-1;i>=1;i--) B.push_back(b[i]-"0"); vector C=add(A,B); for(int i=C.size()-1;i>=0;i--) cout<=1;i--) A.push_back(a[i]-"0"); for(int i=b.size()-1;i>=1;i--) B.push_back(b[i]-"0"); if(cmp1(A,B)) { cout<<"-"; vector C=sub(A,B); for(int i=C.size()-1;i>=0;i--) cout< C=sub(B,A); for(int i=C.size()-1;i>=0;i--) cout<
高精度乘法高精度乘低精度高精度乘法与前面有所不同,在我们用竖式计算乘法时,都是一位对一位的,而在这里因为 \(b\) 比较小,所以我们直接拿大数的每一位去乘上 \(b\) 就行了,那么我们还是拿一个竖式举例:
先模拟一下这个例子:
\(C_0=(3×12)~mod~10=6\) \(t_1=3×12/10=3\) \(C_1=(2×12+t_1)~mod~10=7\) \(t_2=2×12/10=2\)
\(C_2=(1×12+2)~mod~10=4\) \(t_3=1×12/10=1\) \(C_3=t_3=1\)
那么最终的结果就是 1476
我们用循环遍历 \(A\) 的每一位就行了
如果最后 \(t\neq0\),那么就添上 \(t~mod~10\),注意因为我们是直接乘上 \(b\) 所以进位不一定是个位数,要用一个循环来做
代码模板#include #include #include using namespace std;vector mul(vector& A,int B){int t=0;vector C;for(int i=0;i>a;cin>>B;vector A;for(int i=a.size()-1;i>=0;i--) A.push_back(a[i]-"0");vector C=mul(A,B);for(int i=C.size()-1;i>=0;i--) cout<
高精度乘高精度因为两个数都很大,所以我们按照手算的方式进行计算,首先先举个例子:
我们可以发现 \(A_0×B_0\) 对应 \(C_0\) \(A_1×B_0\) 对应 \(C_1\) \(A_2×B_0\) 对应 \(C_2\) 以此类推……
我们可以得出 \(A_i×B_j\) 对应 \(C_i\)\(_+\)\(_j\)
那么进位 \(t\) 就等于\(C_i\)\(_+\)\(_j\)\(/10\)
与大数乘小数一样,最后还要添上 \(t\),不过这里是模拟手算,不需要再循环了
因为不能直接往后添数,所以我们的答案先初始化长一点,否则无法存储 vector
最后记得去除前导0
代码模板#include #include #include using namespace std;vector mul(vector& A,vector& B){vector C(A.size()+B.size()+7,0);for(int i=0;i1&&C.back()==0) C.pop_back();return C;}int main(){string a,b;cin>>a; cin>>b;vector 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");vector C=mul(A,B);for(int i=C.size()-1;i>=0;i--) cout<
注意:\(t\) 在一轮用完后要及时初始化为0,另外 \(t\) 一定要赋值为 \(C_i\)\(_+\)\(_j/10\),因为当重叠时可能加法上又有进位。
高精度除法大数除小数首先,回想一下我们是怎么用竖式算除法的
我们可以发现几个变量分别是被除数、除数、商、余数
我们使用一个变量 \(r\) 来存储余数
因为计算机不像人那么聪明,所以一位一位来
首先看1,1除11不够,商0,余1
再看2,因为现在余1,所以变成10+2,12除11够,商1,余1,结束
我们就可以得到 \(r=r×10+A_i~mod~B\),\(C_i=r×10+A_i~/B\)
注意因为我们除法是从前往后的,所以去除前导0的时候要先进行翻转
代码模板#include #include #include #include using namespace std;vector div(vector& A, int& B,int& r){r=0; vector C;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;}int main(){string a;cin>>a;vector A; int B;cin>>B;for(int i=a.size()-1;i>=0;i--) A.push_back(a[i]-"0");int r;vector C=div(A,B,r);for(int i=C.size()-1;i>=0;i--) cout<
压位因为数组一个位置可以存很大的数,所以我们只存一个数有点浪费,所以我们可以使用压位这个技巧
我们先开两个全局变量 \(N=x\) \(M=10^x\) (x为你想压的位数)
输入的时候改成
int st=max(0,1-N+1),len=i-st+1;A.push_back(a.substr(st,len)-"0");
注意所有 \(/10~mod~10\) 的操作均要修改成 \(/M~mod~M\)输出的时候要先输出首位,因为输出的时候有可能不一定正好是 \(x\) 位数,要使用 printf("%04d",C[i])
(以4位举例)所以当输出完首位后,从C.size()-2
开始
首先,我们先算出整数部分,因为计算机不像手算,直接算出就可以了,不需要像手算一样一位一位算
然后我们回想一下手算是怎么算小数部分的,我们将上一位算得的余数乘10再除以除数就行了
示意图
代码模板//c是位数digit[0]=a/b;a%=b;for(int i=1;i<=c+1;i++){a*=10; digit[i]=a/b; a%=b;}cout<
四舍五入由于小数会出现循环,所以题目一般会给出一些要求,例如最后一位四舍五入
四舍五入即为 当数 \(>=5\) 进一位,\(<5\) 时舍去
不过我们需要注意,进位的时候可能会出现“多米诺骨牌”
例如 9.99999... 进位后会变成10.00000....,所以我们需要使用循环来处理
注意进位到整数位如果变成10不用管,因为我们是直接输出整数位的
代码模板if(digit[c+1]>=5) digit[c]++;for(int i=c;i>0;i--){if(digit[i]>=10) { digit[i]-=10; digit[i-1]++; }}
8进制转10进制因为8进制小数能完美转换成10进制小数,所以我们就不用管保留几位的问题
举个例子,0.75如何转换成10进制呢?
\(7/8^1+7/8^2=0.953125\) 这样就转换完成了,不会的去补初一数学
于是我们就可以模拟手算(见上文保留?位),再用数组进行存储就行了,因为题目也给出了范围 \(0 还要注意进位的问题,与之前一样都是”多米诺骨牌“,所以要用循环 还要开一个变量,记录数组里面一共有多少位了方便输出 坑点: 答案有可能变成1点几,例如当输入为 0.898 时,网上很多人都没有注意到这一点,为此我们从数组的第一位开始,第0位专门留着防止进位变1 首先我们分析一下题目是什么意思,相信大家在上幂这一课,老师都讲过这个故事 第一个格子有 \(2^0\) 粒米,第二个格子有 \(2^1\) 粒米,…… 我们在这里直接从1开始,不然全是0,第20个格子就遍历19次 注意这题的说法略微有些歧义,从第 \(n\) 个到第 \(m\) 个,应该第一次从 1 遍历到 \(n-1\) 第二次从 1 遍历到 \(m\),然后将两次结果一减就行了,注意也要使用高精 接下来就是三位一撇的问题了,我是先将正序的结果存储下来,然后再根据位数对3进行取模,注意最后一位不要有逗号 我们可以发现这题就是高精度乘低精度我们直接将上一次得到的结果再乘当前的数就行了 标签:
pow
返回的是double
类型,所以要进行强转,因为 \(3^1\)\(^5\) 非常大,使用long long
,所以 与它进行计算的 \(x\) 也必须是long long
类型
棋盘放米#include
n的阶乘#include
#include
高精度 简介众所周知,在计算机中,每个数据类型都是有存储上限的,
2023-08-15e公司讯,晶科能源(688223)8月15日晚间公告,拟以3亿元-6亿元回购股份
2023-08-15“我发在自己社交平台上的照片,却莫名其妙被别人‘挂厕’了,对方发表
2023-08-15没有想到,顺手写的一篇文章竟然引起几万人的围观,看来这几天的高
2023-08-15丹纳赫案例研究(下):国内产业并购、天时地利人和
2023-08-15翼虎(参数|询价)是中国和美国合资的车,以福特翼虎2019款EcoBoost180两
2023-08-15很多人对电视剧李小龙传奇全集在线观看,电视剧李小龙传奇不是很了解那
2023-08-15近日,陕西省工业和信息化厅公示2023年DCMM(数据管理能力成熟度评
2023-08-15以地名建设为乡村发展赋能,让乡村要素流动更便捷、更智能地名是乡村治
2023-08-1514日,周杰伦在社交平台晒出与儿子的合照,自称“三宝爸”。他与儿子罗
2023-08-15中核科技融资融券信息显示,2023年8月14日融资净偿还万元;融资余额亿
2023-08-158月14日,景顺长城内需贰号混合最新单位净值为1 311元,累计净值为3 79
2023-08-15裹挟与较量:王传福哽咽高呼“在一起”背后
2023-08-15如何使眼睛变大变亮视频,如何使眼睛变大变亮这个很多人还不知道,现在
2023-08-15收集了机械键盘键盘不灵怎么办这个问题相关的信息,并进行了分类整理,
2023-08-14证券时报e公司讯,卫宁健康(300253)8月14日晚间公告,公司此前公告,公
2023-08-141、食指按2品四弦线。2、无名指按4品五弦线。3、尾指按4品三弦。本文到
2023-08-144年合作7位全明星,输球怪队友无能!这老大当的,毫无领袖气质啊,费城,
2023-08-14通关区副本,可以在boss室获得时空石。积累足够的时空石,与乔纳森交换
2023-08-14针对母婴用品专卖店和超市等重点场所,开展现场检查,对涉及的不合格儿
2023-08-14电脑操作系统不能进入怎么办?开机进不了操作系统,一般都会还原或者重
2023-08-14交易商品牌 产地交货地最新报价LDPE 牌号:2426H;用途级别:薄膜级中石
2023-08-14中国经济网8月14日讯(记者景远)近期,受台风“杜苏芮”影响,华北、
2023-08-14有分析指出,WeWork的困境一定程度上也是全球共享办公行业的一个缩影。
2023-08-14殷商一方的武将:闻太师、孔宣、魔家四将、张奎、张桂芳、风林、辛
2023-08-14近日,受台风“杜苏芮”“卡努”及其他气象因素影响,吉林省将迎来入汛
2023-08-148月14日,蓝鲸财经从知情人士处获悉,龙湖企业拓展已将17亿人民币拨入
2023-08-14普京突然发了一个申明:核战争没有赢家,决不能发动核战争。怎么普京突
2023-08-14HELLO,我是智能手机网小溪,我来为大家解答以上问题。金山密码保险箱
2023-08-14PCB设计方法和技巧-学好PCB设计的方法之一就是通过前辈的作品学习前辈
2023-08-147月26日22时15分,随着35千伏猛狮克拉玛依光伏一电站成功并网,新疆电
2023-08-148月14日讯截至上午10点鹏扬30年国债ETF511090涨025债市方面30年期国债
2023-08-14截至本公告日,泛海集团及其一致行动人持有本行2,219,553,255股无限售
2023-08-14合肥市四部门联合约谈网约车平台企业
2023-08-14上周,央视财经频道点名了多个APP存在“自动续费”问题,引发舆论热议
2023-08-14今年1至6月,家电行业企业实现营收9145亿元,同比增长7 1%;实现利润674
2023-08-14赣锋锂业(01772)发布公告,该公司于近日接到公司股东李良彬先生将其
2023-08-14金融支持实体经济离不开监管部门积极引导。近日,国家金融监督管理总局
2023-08-14直播吧8月14日讯据转会专家罗马诺报道,柏林联合在考虑引进博努奇。罗
2023-08-14,你们好,今天0471房产来聊聊一篇孔阳:且说说我自己,孔阳:且说说我
2023-08-14来源:北京日报客户端8月13日,新华通讯社社长傅华在北京会见美联社社
2023-08-13在博德之门3中,我们通过空格键就可以跳过当前的动画或者对话,从而进
2023-08-138月10日,静安寺街道召开“五经普”动员大会暨第一次“两员”培训会,
2023-08-13外交部网站消息,当地时间2023年8月13日,柬埔寨首相洪森在金边会见到
2023-08-13为了让辖区青少年感受科技的魅力,了解工业的发展,认识劳动的价值,8
2023-08-132023年7月10日普高录取日报-国家优师专项录取情况统计表2023年7月10日
2023-08-138月11日一大早,在河北省涿州市刁窝镇小柳村村口,村党支部书记、党员
2023-08-13跟随大河网记者的镜头,打卡郑州新老地标,体验不一样的夜生活。热闹非
2023-08-13智通财经APP获悉,中泰证券发布A股策略报告指出,就投资建议而言,当前
2023-08-13今年夏天自由市场开启之后,哈登选择了执行下赛季的球员选项,这不是因
2023-08-13韩国旅游和酒店业因应中国开放赴韩旅行团,开发专门为中国游客而设的旅
2023-08-13做股票投资,短线交易无疑非常具有诱惑力。因为短线交易可以把有限的资
2023-08-131、你可以去土豆网下载。2、在看的下方有下载。3、你只要下个土豆下载
2023-08-13此前巴西公布了一份25人的初选大名单,内托是巴西目前的最大牌球员,上
2023-08-13限时入园!安徽一知名景区发布提醒
2023-08-13另一位在下半区晋级的韩国选手是李恩惠,她遇到了东道主巴西队的一姐布
2023-08-13扬子晚报网8月12日讯(记者张晨瑆张昊)北京时间8月12日,在2023赛季中
2023-08-13大家好,小万来为大家解答以上的问题。实验烧伤外科学,关于实验烧伤外
2023-08-13原标题:海南上半年新增减税降费及退税缓费82 6亿元海南日报记者8月11
2023-08-13国产摩托车不少车型都被人吐槽过,设计车的设计师自己都不骑车吧。事实
2023-08-12iPad游戏下载排行榜2012ipad游戏排行榜对于很多iPad用户来说,iPad有什
2023-08-12西安市胸科医院党委副书记、院长李向前涉嫌严重违纪违法,经西安市纪委
2023-08-12据迈奇化学消息,8月11日,新迈奇大湾区生产总部基地动工仪式在广东中
2023-08-12艾草健康液制作原料:艾草叶、红糖、塑料等容器制作方法:第一,原料与
2023-08-12近日,吉林高速公安长春分局接到一名驾驶人举报,称自己在长春绕城高
2023-08-12长城、比亚迪大佬斗嘴!要在一起还是打一架?,比亚迪,王传福,电动车,月
2023-08-12随餐可乐要收包装费、奶茶配料分装收取包装费、烧烤烤串每一串都收包装
2023-08-12只有拥有健康的身体才能让我们的生活品质更好的提高,但是在生活中日常
2023-08-12易车讯我们从海外媒体获悉,奔驰将在8月18日开幕的美国圆石滩车展上亮
2023-08-128月11日晚间,景林资产在美国证券交易委员会(SEC)公布了今年二季度末
2023-08-12正常的电影宣发,都是用精彩的片段制成预告,吸引观众走进影院。不论电
2023-08-12未完待续 原作者Beg的呆站页面:Beg& 39;sprofile-Derpibooru(trixie
2023-08-12来为大家解答以上问题,云浏览器网址,阿云浏览器很多人还不知道,现在
2023-08-121、女子医院其实就是妇儿医院。2、像北京比较早的就是五洲女子医院。3
2023-08-12白羊座你过去的浪漫兴趣可能会回到你的生活中,度过一个难忘的周末。爱
2023-08-12金观平:标准引领氢能产业高质量发展---国家标准委联合多部门日前印发
2023-08-12【西安市喂子坪村山洪泥石流已造成2人死亡16人失联抢险救援正在进行】
2023-08-12燕麦科技融资融券信息显示,2023年8月11日融资净偿还万元;融资余额万
2023-08-128月11日,招商上证消费80ETF最新单位净值为0 5759元,累计净值为2 2776
2023-08-121、南校区外面没有银行里有个银行是建设银行。本文到此讲解完毕了,希
2023-08-12《9:55p m》主唱:薛凯琪作曲:方大同丨填词:陈咏谦编曲:EdwardChan
2023-08-12次日,早上九点。美美的一觉过后,姐姐们已经陆续起床,而龙崽子则还赖
2023-08-11路畅科技00281308月11日在投资者关系平台上答复了投资者关心的问题投资
2023-08-11近日, 为解绑支付宝民警帮办45张证明 的词条冲上微博热搜,引发网友关
2023-08-11上证报中国证券网8月11日晚间,掌趣科技发布2023年半年度报告。上半年
2023-08-11Vulture杂志采访——翻译:悦宝在过去的十几年中,以钢铁侠和福尔摩斯
2023-08-11格隆汇8月11日丨有投资者向华阳集团(002906)(002906 SZ)提问,“请问贵
2023-08-11格隆汇8月11日丨联康生物科技集团(00690 HK)宣布,下列事项自2023年8月
2023-08-11IT之家8月11日消息,荣耀官方宣布荣耀手机地震预警功能已在全国范围内
2023-08-11来源:中国新闻网中新网8月11日电据美国广播公司报道,一名24岁女子因
2023-08-11每平不到1 2万,济南起步区示范区房屋评估价格公布,征收,济南市,评估价
2023-08-11为了营造更加舒适宜居的生态环境,经过近十年打造,曹杨新村一带的林荫
2023-08-11社会经济水平不断提升和科技的不断进步给人们的生活带来许多新变化,人
2023-08-11新华社记者伍志尊摄 8月9日,武汉三镇队球员马尔康(左一)在比赛
2023-08-11交易商品牌 产地交货地最新报价有机硅类消泡剂 含量10%潍坊前线默克化
2023-08-11上证报中国证券网讯8月11日,金融科技股表现疲软,恒银科技触及跌停,
2023-08-118月11日山东地区氟化铝行情暂稳,报价8500-9200元 吨。原材料氢氟酸行
2023-08-11京东京造Z9Elite2代质量反馈?实情爆料细节基本没有气味,很环保安装也
2023-08-11墨玉里显青色通常指的是墨玉中的青田玉。青田玉是一种常见的玉石,得名
2023-08-11我们平素一定会有很多碎片时间与闲暇时光,又或者是在每天上下班的路上
2023-08-11Copyright © 2015-2023 京津冀水产网版权所有 备案号:京ICP备2022022245号-12 联系邮箱:434 922 62 @qq.com