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

开学成功加入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,0,sizeof(a)); memset(b,0,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("%d\n",flag2); if(flag2==0) { memset(a,0,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,0,sizeof(a));a[0]=1;return 0;} //单独处理key=0for(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]+1while(a[i]>0)

你的内心会被洗成一片空白,自由而宁静,

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

相关文章:

你感兴趣的文章:

标签云: