高精度
2015-09-16 20:12
253 查看
之前的模板有一点点错误,在乘法中自己自作多情先预处理了一下,深表歉意。
现在做了更正,应该没问题了。
不过仍然不完整,运算中是不包含负数的,结构体中的neg没有任何卵用→.→。
对于压位,只需要改变P就可以,P = 10^n即压n位。
对于乘法,压位后仍然是正常的乘法,P进制的乘法而已,想象10进制的竖式即可,只是数变成了P进制。
高精除高精这里用的是倍增法,借用了乘法和加法,以及好多运算符,所以很慢、很慢、很慢、慢。不过高精除单精还是可以的。
发现直接定义运算符比函数式的用起来更方便,就把那份函数式的拿掉了。
现在做了更正,应该没问题了。
不过仍然不完整,运算中是不包含负数的,结构体中的neg没有任何卵用→.→。
对于压位,只需要改变P就可以,P = 10^n即压n位。
对于乘法,压位后仍然是正常的乘法,P进制的乘法而已,想象10进制的竖式即可,只是数变成了P进制。
高精除高精这里用的是倍增法,借用了乘法和加法,以及好多运算符,所以很慢、很慢、很慢、慢。不过高精除单精还是可以的。
发现直接定义运算符比函数式的用起来更方便,就把那份函数式的拿掉了。
struct BigInt{ int a[M], h; bool neg; BigInt(){ h = neg = 0; memset(a, 0, sizeof a); } void read(){ memset(s, 0, sizeof s); scanf("%s", s+1); int len = strlen(s+1); h = 1; for(int i = len, j = 1; i; i--, j *= 10){ if(j == P){ j = 1; h++; } a[h] += (s[i]-'0')*j; } } void read(char *s){ int len = strlen(s); h = 1; for(int i = len-1, j = 1; i >= 0; i--, j *= 10){ if(j == P){ j = 1; h++; } a[h] += (s[i]-'0')*j; } } bool operator < (BigInt k) const { if(h > k.h) return 0; if(h < k.h) return 1; for(int i = h; i; i--){ if(a[i] > k.a[i]){ return 0; } if(a[i] < k.a[i]){ return 1; } } return 0; } bool operator > (BigInt k) const { if(h > k.h) return 1; if(h < k.h) return 0; for(int i = h; i; i--){ if(a[i] > k.a[i]){ return 1; } if(a[i] < k.a[i]){ return 0; } } return 0; } bool operator == (BigInt k) const { if(h != k.h) return 0; for(int i = h; i; i--){ if(a[i] != k.a[i]) return 0; } return 1; } BigInt operator + (BigInt k) const { BigInt res = *this; res.h = max(res.h, k.h); for(int i = 1; i <= res.h; i++){ res.a[i] += k.a[i]; res.a[i+1] += res.a[i] / P; res.a[i] %= P; } while(res.a[res.h+1]) res.h++; return res; } BigInt operator - (BigInt k) const { BigInt res = *this; for(int i = 1; i <= k.h; i++){ res.a[i] -= k.a[i]; if(res.a[i] < 0){ res.a[i] += P; res.a[i+1]--; } } while(!res.a[res.h] && res.h) res.h--; return res; } BigInt operator * (BigInt k) const { BigInt res; if(!h || !k.h) return res; for(int i = 1; i <= h; i++) for(int j = 1; j <= k.h; j++){ res.a[i+j-1] += a[i] * k.a[j]; res.a[i+j] += res.a[i+j-1] / P; res.a[i+j-1] %= P; } res.h = h + k.h + 2; //因为压位,i位乘j位不一定是i+j位,所以先把位数开大一点,再减去 while(!res.a[res.h] && res.h) res.h--; return res; } BigInt operator * (int k) const { BigInt res; if(!h || !k) return res; for(int i = 1; i <= h; i++){ res.a[i] += a[i] * k; res.a[i+1] += res.a[i] / P; res.a[i] %= P; } res.h = h + 2; while(!res.a[res.h] && res.h) res.h--; return res; } BigInt operator / (BigInt k) const { BigInt res, two; two.h = 1; two.a[1] = 2; #define RES k*res+k while(RES < *this || RES == *this){ BigInt t; t.h = t.a[1] = 1; while(k*(t+res)*two < *this || k*(t+res)*two == *this){ t = t * two; } res = res + t; } return res; } BigInt operator / (int k) const { BigInt res; int x = 0; for(int i = h; i; i--){ res.a[i] = (x*P + a[i]) / k; x = (x*P + a[i]) % k; } res.h = h; while(!res.a[res.h] && res.h) res.h--; return res; } BigInt operator % (L k) const { BigInt res = *this - (*this / k) * k; while(!res.a[res.h] && res.h) res.h--; return res; } void print(){ if(!h) { //默认0是0位数→→ printf("0"); return; } if(neg) printf("-"); printf("%d", a[h]); for(int i = h-1; i; i--){ int k = a[i], len = 1; while(k){ len *= 10; k /= 10; } if(len==1) len *= 10; // when a[i] == 0 while(len < P){ printf("0"); len *= 10; } printf("%d", a[i]); } } };
相关文章推荐
- Oracle环境下的Hibernate方言配置
- intent和intent-filte
- Hibernate学习随笔-----关系映射(3)单向1-N关联
- 同时找最大最小值
- PostgreSQL数据库简介
- 软工视频5-7章
- 数据的4种逻辑结构与4种存储结构
- 安卓中的外部存储ExternalStorage,工具类
- zoj1729最小表示法(模板题)
- 用宏定义实现函数值互换
- Android 4.4 kitkat以上及以下根据uri获取路径的方法
- 迷你MVVM框架 avalonjs1.5.2 发布
- MySQL性能优化的最佳20+条经验
- Java "==","equals",hashcode
- 利用ORACLE实现数据抽样(sample block)
- UIButton
- samba详解
- 前端性能优化(六)
- css取消div蹭上的鼠标点击事件
- 自己写的下载数据的方法(GET和POST两种)(已经封装)