关于高精度问题的自我总结
来源:互联网 发布:如何修改电脑mac地址 编辑:程序博客网 时间:2024/05/18 12:03
关于高精度问题的自我总结
高精度这个问题说起来很头疼啊,也算是最近接触的算法,这里做个总结吧,做个自己的模板也好看。
加法
先是加法吧,很简单,网上也有很多的资料,包括UVA上的BIG的第一题也就高精度加法,就是数组处理,贴个自己经常用的模板:
#include<stdio.h>#include<string.h>#define MAX_SIZE 10000 + 10#define ZERO 0int main(){ char x[MAX_SIZE],y[MAX_SIZE]; int a[MAX_SIZE]={ZERO},b[MAX_SIZE]={ZERO}; int L1,L2; int i,j; gets(x); /*输入一个数字,处理成字符串*/ L1=strlen(x); gets(y); L2=strlen(y); for(i=0,j=L1-1;i<L1;i++,j--) a[j]=x[i]-'0';/*将字符串元素转化为数组储存*/ for(i=0,j=L2-1;i<L2;i++,j--) b[j]=y[i]-'0'; /*这里需要倒序储存,仔细一想就知道了*/ for(i=0;i<(L1>L2?L1:L2);i++) { a[i]+=b[i]; if(a[i]>=10) { a[i]%=10; a[i+1]++; } } /*这里就是进位了,加法的一次最多进一位,所以直接进就可以了*/ for(i=MAX_SIZE-10,j=0;i>=0;i--) { if(j==1) printf("%d",a[i]); else if(a[i]!=0) { printf("%d",a[i]); j=1; } } /*这里就是跳过空格了*/ if(j==0) printf("0\n"); /*特例的考虑*/}
乘法的话也没什么,就是考虑最后进位吧,不能像加法一样,乘一次就进一次
也是贴个自己用的模板.
乘法
#include<stdio.h>#include<string.h>#define MAX_SIZE 10000 + 10#define ZERO 0int main(){ char x[MAX_SIZE],y[MAX_SIZE]; int a[MAX_SIZE]={ZERO},b[MAX_SIZE]={ZERO}; int sum[MAX_SIZE]={ZERO}; int L1,L2; int i,j; gets(x); /*输入一个数字,处理成字符串*/ L1=strlen(x); gets(y); L2=strlen(y); for(i=0,j=L1-1;i<L1;i++,j--) a[j]=x[i]-'0';/*将字符串元素转化为数组储存*/ for(i=0,j=L2-1;i<L2;i++,j--) b[j]=y[i]-'0'; /*这里需要倒序储存,仔细一想就知道了*/ for(i=0;i<L1;i++) for(j=0;j<L2;j++) sum[i+j]+=a[i]*b[j]; /*下面就是核心了,进位问题*/ for(i=0;i<MAX_SIZE;i++) { sum[i+1]+=sum[i]/10; sum[i]%=10; } for(i=MAX_SIZE-10,j=0;i>=0;i--) { if(j==1) printf("%d",sum[i]); else if(sum[i]!=0) { printf("%d",sum[i]); j=1; } } /*这里就是跳过空格了*/ if(j==0) printf("0\n"); /*特例的考虑*/ }
减法
这个和加法同理吧,先判断哪个数比较大,永远用大减下,之后看是负的加个‘-’
#include<stdio.h>#include<string.h>#define MAX_SIZE 10000 + 10#define ZERO 0int judge(int x[],int y[]) /*判断哪个数比较大*/{ int i; for(i=MAX_SIZE-10;i>=0;i--) { if(x[i]>y[i]) return 1; if(x[i]<y[i]) return 0; } return 1;}int main(){ char x[MAX_SIZE],y[MAX_SIZE]; int a[MAX_SIZE]={ZERO},b[MAX_SIZE]={ZERO}; int c[MAX_SIZE]={ZERO}; int L1,L2; int i,j,w; gets(x); /*输入一个数字,处理成字符串*/ L1=strlen(x); gets(y); L2=strlen(y); for(i=0,j=L1-1;i<L1;i++,j--) a[j]=x[i]-'0';/*将字符串元素转化为数组储存*/ for(i=0,j=L2-1;i<L2;i++,j--) b[j]=y[i]-'0'; /*这里需要倒序储存,仔细一想就知道了*/ w=judge(a,b); for(i=0;i<(L1>L2?L1:L2);i++) { if(w==1) /*用大数去减小数*/ c[i]=a[i]-b[i]; else c[i]=b[i]-a[i]; } /*最后处理进位问题*/ for(i=0;i<MAX_SIZE;i++) if(c[i]<0) { c[i]+=10; c[i+1]--; } if(w==0) printf("-"); for(i=MAX_SIZE-10,j=0;i>=0;i--) { if(j==1) printf("%d",c[i]); else if(c[i]!=0) { printf("%d",c[i]); j=1; } } /*这里就是跳过空格了*/ if(j==0) printf("0\n"); /*特例的考虑*/ }
阶乘
根据刘汝佳的书上的改了一个自己用的舒服的模板
#include<stdio.h>#define ZERO 0#define MAX_SIZE 1000 + 10int main(){ int n; int i,j,k; int array[MAX_SIZE]={ZERO};/*初始化*/ scanf("%d",&n); array[0]=1; for(i=2;i<=n;i++) { for(j=0;j<MAX_SIZE;j++) { array[j]*=i; } /*每次乘完就进位*/ for(j=0;j<MAX_SIZE;j++) { array[j+1]+=array[j]/10; array[j]%=10; } } for(i=MAX_SIZE-10,k=0;i>=0;i--) {/*跳过0逆向输出*/ if(k==1) printf("%d",array[i]); else if(array[i]!=0) { k=1; printf("%d",array[i]); } }}
除法
除法一开始有点不知所措,上网找的模板参考了才知道除法也分很多种,先说一下小数点后高度精确的吧
#include<stdio.h>int main(){ int x,y,n,w; scanf("%d%d%d",&x,&y,&n);/*输入2个数x,y,精确到小数点后n位*/ printf("%d.",x/y);/*先输出整数的部分*/ x=x%y; while(n>0) { x=x*10; /*这里就像小学生除法一样*/ w=x/y; printf("%d",w); if(x==0) break; x=x-w*y; n--; }}
0 0
- 关于高精度问题的自我总结
- 关于Arduino问题查找的自我总结
- Exponentiation -高精度求幂的自我总结
- 高精度之关于高精度的其他问题
- 关于MD5码的一些自我总结
- 关于c语言编程的自我总结
- 关于软件开发模型的自我总结
- 关于AOP使用的自我总结
- 关于FPGA的自我小总结
- 关于operator=的自我赋值问题
- Java,InputStream,Socket阻塞.(关于HTTP请求的IO问题自我总结)
- 双向链表的问题-自我总结
- 过滤驱动的问题-自我总结
- 由版本问题引发的自我总结
- 经典进程的同步问题自我总结
- 关于<a></a>标签的简单的自我总结
- 关于webservice一些自我总结
- 自我总结和一些关于未来方向的疑惑
- Where's Waldorf? -uva手记
- 解决mysql 1040错误Too many connections的方法
- 当更换cocos2d-x版本时,删除VS2010下面的cocos2d-x模板方法 VA默认路径
- java调用oracle存储过程的自定义类型(可变数组)。
- 用代码给 core data property 设置默认值
- 关于高精度问题的自我总结
- PHP类的静态方法和静态变量
- 手机号码验证,邮箱,车牌验证
- zoj-1789
- 黑马程序员------- IO-------
- Android中在主线程与在子线程中更新UI的探索
- 半年C++学习有感
- Fermat vs. Pythagoras -基础数论(深刻总结)
- linux 的ioctl()函数