您的位置:首页 > 其它

高精度

2015-09-16 20:12 190 查看
之前的模板有一点点错误,在乘法中自己自作多情先预处理了一下,深表歉意。

现在做了更正,应该没问题了。

不过仍然不完整,运算中是不包含负数的,结构体中的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]);
}
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: