众所周知,计算机数据类型的长度是有限的,因此在处理较大的数据时候会发生数据溢出,此时聪明的我们需要想办法处理这批数据,那么我们如何处理呢?答案是用数组存储数据,再做批量处理。
所谓大数加法,就是在我们计算机数据无法存储的大数据时进行的加法运算。那我们如何实现大数加法呢,我们可以用数组,链表等结构来分段存储大数据,这里我采用数组进行大数运算的描写。假如我们输入123456789123456+123这两个数据时,如果要发生相加的运算,那么第一个数字怎么存储呢?答案是用数组来存,准确点说是字符数组,我们把这两个当成一个字符串输入到一个字符数组中,然后再进行倒序处理,为什么要倒序处理呢?比如说123456789123456+123,这里我们把6和3相加,5和2相加,4和3相加,但是在程序中是否表达对位相加不便呢?还有一个优点是我们可以很方便的进行进位处理,所以我们采用倒序处理。那怎么倒序呢,用整形数组从下表0开始存字符数组从后往前推的字符-‘0’(这里解释一下减字符0是为了从字符转成相应的数字,如果不了解可以去查找Ascii码表)。两个数组依次进行这个操作后,那么用一个sum数组进行相加即可。具体代码实现如下:
#include"bits/stdc++.h"#include"cstring"usingnamespacestd;chars1[600],s2[600];inta[600],b[600];intsum[1200];intmain(){inti,j,res;intlength1,length2;intlen;cin>>s1;cin>>s2;length1=strlen(s1);length2=strlen(s2);j=0;for(i=length1-1;i>=0;i--)a[j++]=s1[i]-'0';//倒转j=0;for(i=length2-1;i>=0;i--)b[j++]=s2[i]-'0';//倒转if(length1>length2)len=length1;//遍历到最长的那个数字elselen=length2;res=0;//存进位for(i=0;i 大数减法采用大数加法的思路存储数据,处理数据时从低位开始往高位减,例如123456-123逆转后就是654321-321,这时候6-3,5-2,4-1,然后其他的可以直接赋给minus数组了,如果被减数相应位数小于减数相应位数的话,我们采用借位的方式。例如1234-345,4-5<0,往前借位,借位后前一位-1,也就是3-1,(这里我默认是逆转过后的数组)。如果被减数小于减数呢?我们怎么判断呢?这时候我们只需要判断如果被减数的长度小于减数的长度,那么我们可以直接输出一个负号,然后再用减数-被减数。有人又问了,那如果两个数位数相等,且被减数小于减数呢?此时我们只需要把逆转后的数组从前往后遍历,如果发现被减数位数小于减数位数的话,我就可以判断出来了。直接输出一个负号,然后用减数减去被减数,总的来说思路就是如果被减数大于减数,那么可以直接减去就行;如果被减数小于减数,就直接输出一个负号,然后用减数减去被减数。例如123456-789,123456是被减数,789是减数,别搞混了啊。接下来贴出我的代码实现(代码有点长,有能力的小伙伴可以自行实现): 不知道小伙伴们是否了解过计算器的原理,我曾有幸在图书馆了解过一本有关计算器原理的书,里面就介绍了一下计算器的四则运算,所谓乘法就是多次加法,小学时候我们还不懂乘法的时候计算5*3,就会把5加上三次,其实这个就是乘法的原理——对同一个数累加。那我们如何用程序实现它呢,比如说123*45我们逆转后为321*54,3*5就是15个1,3*4就是12个十,2*5就是10个十,2*4就是8个一百,然后1*5就是五个一百,1*4就是4个1千,然后将结果进位即可。具体代码实现如下: 然而我们可以百度搜索阶乘计算器后可以得出 那么时哪里出错了呢,答案是数据类型长度不够。所以我们应该改变策略,用数组存储数据,再批量处理。接下来我们先介绍两个计算阶乘位数的算法。 1.用对数函数求解阶乘位数 2.用Stirling公式求解位数。再介绍如何进行阶乘的计算。 lg1+lg2+lg3+lgn,由对数函数特性可知,lga+lgb等于lga*b,这时候我们发现真数a*b就可以替换成我们的1和2-n。但此时为什么不会越界呢,因为lg函数返回的是一个double型,所以我们用一个double型的数去存这个值就行,这个值是较小的,所以不会发生数据溢出的情况。需要注意的是我们的位数初始化为1,输出的时候应该把位数取整后输出。具体代码如下: #include"bits/stdc++.h"#include"cmath"usingnamespacestd;constdoublee=2.7182818284;//小数越多精度越高constdoublePi=3.1415926535;intmain(){intres=0;intn;cin>>n;res=0.5*log10(2*Pi*n)+n*log10(n/e);cout< #include"stdio.h"intmain(){inti=1,high=0,tag=0;//tag为低位,high为高位,i为阶乘值inta[1000]={0};//计算精确度为7000位a[high]=1;//把第一次运算赋初值为1while(i<=100){for(tag=0;tag<=high;tag++)a[tag]*=i;if(a[high]>=1000000)high+=1;for(tag=0;tag<=high;tag++){if(a[tag]>=1000000){a[tag+1]+=a[tag]/1000000;a[tag]=a[tag]%1000000;}}i++;}tag=high;while(high>=0){if(high==tag)printf("%d",a[high]);elseprintf("%06d",a[high]);//这是一个输出小技巧,左边补0,如果是-06d的话是右边补零high--;}return0;}七.总结第一次发表博客,写的不好的地方请及时指出,我会修改的!另外学习是一件很充实又很快乐的事情,一起加油吧!