加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

目前我所掌握最全的高精度(大数)运算(第一次)

发布时间:2020-12-14 02:41:26 所属栏目:大数据 来源:网络整理
导读:开学成功加入acm组,有一种有一种内心 牵挂已久的东西尘埃落定 却又被更大 的力量 牢牢抓住的 压迫感!(妈蛋 寒假没做题! 开学也没怎么做题! 同组已被甩一截! 现在神马都不会 !马上校赛! 还要组队! 没人要我怎么办1 省赛 也要来了! 还有几本书没看!
开学成功加入acm组,有一种有一种内心 牵挂已久的东西尘埃落定 却又被更大 的力量 牢牢抓住的 压迫感!(妈蛋 寒假没做题! 开学也没怎么做题! 同组已被甩一截! 现在神马都不会 !马上校赛! 还要组队! 没人要我怎么办1 省赛 也要来了! 还有几本书没看! 心中满是 ????)

第一篇这样的开头????????? 会不会?压迫我更加努力

!就这样纪念?我的第一篇?报告吧!

前言?是我从网上?看到?对?高精度 觉得?还不错的?描述

前言:由于计算机运算是有模运算,数据范围的表示有一定限制,如整型int(C++中int 与long相同)表达范围是(-2^31~2^31-1),unsigned long(无符号整数)是(0~2^32-1),都约为几十亿.如果采用实数型,则能保存最大的double只能提供15~16位的有效数字,即只能精确表达数百万亿的数.因此,在计算位数超过十几位的数时,不能采用现有类型,只能自己编程计算.
高精度计算通用方法:高精度计算时一般用一个数组来存储一个数,数组的一个元素对应于数的一位(当然,在以后的学习中为了加快计算速度,也可用数组的一个元素表示数的多位数字,暂时不讲),表示时,由于数计算时可能要进位,因此为了方便,将数由低位到高位依次存在数组下标对应由低到高位置上,另外,我们申请数组大小时,一般考虑了最大的情况,在很多情况下,表示有富余,即高位有很多0,可能造成无效的运算和判断,因此,我们一般将数组的第0个下标对应位置来存储该数的位数.如数:3485(三千四百八十五),表达在数组a[10]上情况是:
下标  0?   1 ?? 2??  3??   4  ? 5??? 6??? 7??? 8??? 9 ?
内容  4??  5?   8??  4??   3?   0??? 0??? 0??? 0??? 0
说明:位数?? 个位? 十位? 百位 千位
具体在计算加减乘除时方法就是小学时采用的列竖式方法.
注:高精度计算时一般用正数,对于负数,通过处理符号位的修正.

下面 就用代码和讲解 说明 大数的加减乘 :

大数?首先?我们一般会用?字符串数组?来?保存?它,原因前言就有~!?而且?进行运算时?每一位对应?应该是倒序的?原因?前言也有~!

using namespace std;
const int N=1000;
char str1[N],str2[N];//存大数?的字符串数组
int a[N],b[N];//具体进行模拟每一位运算的整型数组
int compare(int a[],int b[]);//大数比较大小的函数
void add(int a[],int b[]);//
void gminus(int a[],int b[]);
int main()
{
??? memset(a,sizeof(a));
??? memset(b,sizeof(b));
??? cin>>str1>>str2;
??? a[0]=strlen(str1);
??? b[0]=strlen(str2);
??? for(int i=1;i<=a[0];i++)
??????? a[i]=str1[a[0]-i]-'0';
??? for(int i=1;i<=b[0];i++)
??????? b[i]=str2[b[0]-i]-'0';//以上是将存在字符串里的大数逆序读入整型数组

}

//比较两个大数谁大,想法代码都很简单!

int compare(int a[],int b[])
{
??? int i;
??? if(a[0]>b[0])
????? cout<<"前一个数更大"<<endl;
??? if(a[0]<b[0])
????? cout<<"后一个数更大"<<endl;
??? for(i=a[0];i>0;i--)
??? {
??????? if(a[i]>b[i])
????? cout<<"前一个数更大"<<endl;
??????? if(a[i]<b[i])
????? cout<<"后一个数更大"<<endl;
??? }
????? cout<<"两个数一样大"<<endl;//两数相等
}

//模拟两个大数的加法过程,也很简单

void add(int a[],int b[])
{
??? int len_max;
??? len_max=a[0]>b[0]?a[0]:b[0];//判断哪个大数长一些,加到那一步
??? for(int i=1;i<=len_max;i++)
??? {
????? a[i+1]+=(a[i]+b[i])/10;
????? a[i]=(a[i]+b[i])%10;
??? }
??? if(a[len_max+1]>0) //如果大于0,就进一位
??????? a[0]=len_max+1;
??? else
??????? a[0]=len_max;

???? for(int i=a[0];i>0;i--)
??????? printf("%d",a[i]);
}

//模拟减法也很容易可以想到,如果是负数,输出的时候加个负号-.

void gminus(int a[],int b[])//大数减法
{
??? int flag2=compare(a,b);
??? printf("%dn",flag2);
??? if(flag2==0)
??? {
??????? memset(a,sizeof(a));
??????? a[0]=1;
??????? for(int i=a[0];i>0;i--)
??????? printf("%d",a[i]);
??? }
??? if(flag2==1)//a比b大 正常减 a=a-b;
??? {
?????? for(int i=1;i<=a[0];i++)
?????? {
?????????? if(a[i]<b[i])
?????????? {
?????????????? a[i+1]--;
?????????????? a[i]+=10;
?????????? }
?????????? a[i]=a[i]-b[i];
?????? }
?????? if(a[a[0]]==0)
??????? a[0]--;
????? for(int i=a[0];i>0;i--)
??????? printf("%d",a[i]);
??? }
??? if(flag2==-1)//b比a大 a=-(b-a)
??? {
??????? for(int i=1;i<=b[0];i++)
??????? {
??????????? if(b[i]<a[i])
??????????? {
??????????????? b[i+1]--;
??????????????? b[i]+=10;
??????????? }
?????????? a[i]=b[i]-a[i];
??????? }
??????? a[0]=b[0];
??????? if(a[a[0]]==0)
??????????? a[0]--;
????? printf("-");
????? for(int i=a[0];i>0;i--)
??????? printf("%d",a[i]);
??? }
}

//大数乘以小数

int multi1(int a[],long? key) //a=a*key,key是单精度数 ?
{int i,k;
if (key==0){memset(a,sizeof(a));a[0]=1;return 0;} //单独处理key=0
for(i=1;i<=a[0];i++)

a[i]=a[i]*key;//先每位乘起来
for(i=1;i<=a[0];i++)

{a[i+1]+=a[i]/10;a[i]%=10;} //进位
//注意上一语句退出时i=a[0]+1
while(a[i]>0)

{a[i+1]=a[i]/10;a[i]=a[i]%10;i++;a[0]++];}? //继续处理超过原a[0]位数的进位,修正a的位数
return 0;
}

模拟大数乘法,其实一点都不难 (弄懂了之后是不是都会这样说)说实话?之前以为很复杂? 还特地百度?问大神 ~!各种离奇的算法?吓得我以为很难 校赛绝对不会出这种 虐心的题?也没管?以为 我要一直不会 还好今天 队友?给了 xxz大神学长的一个模板 看了一下 推了一遍?竟然 发现我看懂了 就是模拟乘法 竖式计算?很巧妙?运用0这个下表?对?注意?这个地方不能 用前面 a[0]来保存?数组 a的长度 因为????这个算法最核心的部分 就是 利用0的下标 不说那么高深?其实真不难?看一遍就会了 但不知道能记多久!

直接上全部代码

#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int N=1000; char str1[N],str2[N]; int a[N],b[N],c[N]; int main() { ??? cin>>str1; ??? cin>>str2; ??? memset(a,sizeof(a)); ??? memset(a,sizeof(b)); ??? int len_str1=strlen(str1); ??? int len_str2=strlen(str2); ??? for(int i=0;i<len_str1;i++) ???? a[i]=str1[len_str1-i-1]-'0'; ??? for(int i=0;i<len_str2;i++) ???? b[i]=str2[len_str2-i-1]-'0'; ???? for(int i=0;i<len_str1;i++)//核心代码 模拟竖式 乘法 过程?记住这里下标必须从0开始?不能是1 ???? { ???????? for(int j=0;j<len_str2;j++) ???????? { ???????????? c[i+j]+=a[i]*b[j]; ???????????? c[i+j+1]+=c[i+j]/10; ???????????? c[i+j]%=10; ???????? } ???? } ????? int len=len_str1+len_str2; ???? while(!c[len])len--; ???? for(int i=len;i>=0;i--) ??????? cout<<c[i]; ??????? cout<<endl; } 终于?打完 所有我想记录下的?代码和话语~!算了解?这两天的心愿 ,好吧 我承认?我就算写完?这一篇很水的报告,我的a题能力不会有任何的提高,大神们也根本不懈不会来这里看这种没有营养的报告,不管怎样?我终于迈出了写博客的第一步~!(妈蛋?明天 还有c++上机实验 我书都没看~!)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读