更新:2015-02-09
友情提醒:后面我开发了另一种版本的高精度类,鲁棒性会更好。
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
更新:2014-05-05 中午
功能:正整数的加、减、乘、除、取余、大小关系运算。
概述:本文分三个模块——模板、介绍、例题。在“模板”贴出高精度模板的完整不含注释源代码,在“介绍”分节讲解各个功能的原理及要点。在“例题”举出5道UVA的高精度题作为应用举例。
感谢:刘汝佳的《算法竞赛入门经典》,模板的源框架摘自xiaobaibuhei,除法和取余运算借鉴自误@解。当然,集大成和功能的扩展、代码精简,至少有五成还是自己的功劳。
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
模板:建议计算时把较大的数放在左边对较小的数做运算,比如“999+1”而不是"1+999",因为我的模板针对该类型进行了很大的效率优化。另外模板可能因为更新的缘故,跟后面的解说会有细微出入。
#include <iostream>
#include <string>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn = 1000;
struct bign{
int d[maxn], len;
void clean() { while(len > 1 && !d[len-1]) len--; }
bign() { memset(d, 0, sizeof(d)); len = 1; }
bign(int num) { *this = num; }
bign(char* num) { *this = num; }
bign operator = (const char* num){
memset(d, 0, sizeof(d)); len = strlen(num);
for(int i = 0; i < len; i++) d[i] = num[len-1-i] - '0';
clean();
return *this;
}
bign operator = (int num){
char s[20]; sprintf(s, "%d", num);
*this = s;
return *this;
}
bign operator + (const bign& b){
bign c = *this; int i;
for (i = 0; i < b.len; i++){
c.d[i] += b.d[i];
if (c.d[i] > 9) c.d[i]%=10, c.d[i+1]++;
}
while (c.d[i] > 9) c.d[i++]%=10, c.d[i]++;
c.len = max(len, b.len);
if (c.d[i] && c.len <= i) c.len = i+1;
return c;
}
bign operator - (const bign& b){
bign c = *this; int i;
for (i = 0; i < b.len; i++){
c.d[i] -= b.d[i];
if (c.d[i] < 0) c.d[i]+=10, c.d[i+1]--;
}
while (c.d[i] < 0) c.d[i++]+=10, c.d[i]--;
c.clean(