什么时候需要高精度呢？就比如数据规模很大，unsigned long long 都存不下，就需要开一个字符数组来准确地表示一个数。

高精度问题包含很多小的细节，实现上也有很多讲究，暂时先不展开。

- 四则运算
- 快速幂
- 分数
- 对数（？）
- 开根
- 压位高精度

放一个之前的高精度板子吧。

还有一个很好用的[高精度封装类](https://paste.ubuntu.com/p/7VKYzpC7dn/) 10kb 想用可以自行下载。

```c++
#define MAXN 9999
//MAXN 是一位中最大的数字
#define MAXSIZE 10024
//MAXSIZE 是位数
#define DLEN 4
//DLEN 记录压几位
struct Big{
  int a[MAXSIZE],len;
  bool flag;//标记符号'-'
  Big(){len = 1;memset(a,0,sizeof a);flag = 0;}
  Big(const int);
  Big(const char*);
  Big(const Big&);
  Big &operator = (const Big &);//注意这里operator有&，因为赋值有修改……
  //由于OI中要求效率
  //此处不使用泛型函数
  //故不重载
  //istream& operator>>(istream&,  BigNum&);   //重载输入运算符
    //ostream& operator<<(ostream&,  BigNum&);   //重载输出运算符
  Big operator + (const Big &)const;
  Big operator - (const Big &)const;
  Big operator * (const Big &)const;
  Big operator / (const int &)const;
  //TODO: Big / Big;
  Big operator ^ (const int &)const;
  //TODO: Big ^ Big;

  //TODO: Big 位运算;

  int operator % (const int &)const;
  //TODO: Big ^ Big;
  bool operator < (const Big &)const;
  bool operator < (const int &t)const;
  inline void print();
};
//README::不要随随便便把参数都变成引用，那样没办法传值
Big::Big(const int b){
  int c,d = b;
  len = 0;
  // memset(a,0,sizeof a);
  CLR(a);
  while (d > MAXN){
    c = d - (d / (MAXN + 1) * (MAXN + 1));
    d = d / (MAXN + 1);
    a[len++] = c;
  }
  a[len++] = d;
}
Big::Big(const char* s){
  int t,k,index,l;
  CLR(a);
  l = strlen(s);
  len = l / DLEN;
  if (l % DLEN)++len;
  index = 0;
  for(int i = l - 1;i >= 0;i -= DLEN){
    t = 0;
    k = i - DLEN + 1;
    if (k < 0)k = 0;
    g(j,k,i)t = t * 10 + s[j] - '0';
    a[index++] = t;
  }
}
Big::Big(const Big& T):len(T.len){
  CLR(a);
  f(i,0,len)a[i] = T.a[i];
// TODO:重载此处？
}
Big& Big::operator = (const Big& T){
  CLR(a);
  len = T.len;
  f(i,0,len)a[i] = T.a[i];
  return *this;
}
Big Big::operator + (const Big& T)const{
  Big t(*this);
  int big = len;
  if (T.len > len)big = T.len;
  f(i,0,big){
    t.a[i] += T.a[i];
    if (t.a[i] > MAXN){
      ++t.a[i + 1];
      t.a[i] -= MAXN + 1;
    }
  }
  if (t.a[big])t.len = big + 1;
  else t.len = big;
  return t;
}
Big Big::operator - (const Big& T)const{
  int big;
  bool ctf;
  Big t1,t2;
  if (*this < T){
    t1 = T;
    t2 = *this;
    ctf = 1;
  }else {
    t1 =*this;
    t2 = T;
    ctf = 0;
  }
  big = t1.len;
  int j = 0;
  f(i,0,big){
    if (t1.a[i] < t2.a[i]){
      j = i + 1;
      while (t1.a[j] == 0)++j;
      --t1.a[j--];
      //WTF?
      while (j > i)t1.a[j--] += MAXN;
      t1.a[i] += MAXN + 1 - t2.a[i];
    }else t1.a[i] -= t2.a[i];
  }
  t1.len = big;
  while (t1.len > 1 && t1.a[t1.len - 1] == 0){
    --t1.len;
    --big;
  }
  if (ctf)t1.a[big - 1] = -t1.a[big - 1];
  return t1;
}
Big Big::operator * (const Big& T)const{
  Big res;
  int up;
  int te,tee;
  f(i,0,len){
    up = 0;
    f(j,0,T.len){
      te = a[i] * T.a[j] + res.a[i + j] + up;
      if (te > MAXN){
        tee = te - te / (MAXN + 1) * (MAXN + 1);
        up = te / (MAXN + 1);
        res.a[i + j] = tee;
      }else {
        up = 0;
        res.a[i + j] = te;
      }
    }
    if (up)res.a[i + T.len] = up;
  }
  res.len = len + T.len;
  while (res.len > 1 && res.a[res.len - 1] == 0)--res.len;
  return res;
}
Big Big::operator / (const int& b)const{
  Big res;
  int down = 0;
  gd(i,len - 1,0){
    res.a[i] = (a[i] + down * (MAXN + 1) / b);
    down = a[i] + down * (MAXN + 1) - res.a[i] * b;
  }
  res.len = len;
  while (res.len > 1 && res.a[res.len - 1] == 0)--res.len;
  return res;
}
int Big::operator % (const int& b)const {
  int d = 0;
  gd(i,len - 1,0)d = (d * (MAXN + 1) % b + a[i]) % b;
  return d;
}
Big Big::operator ^ (const int& n)const{
  Big t(n),res(1);
//TODO::快速幂这样写好丑= =//DONE:)
  int y = n;
  while (y){
    if (y & 1)res = res * t;
    t = t * t;
    y >>= 1;
  }
  return res;
}
bool Big::operator < (const Big& T)const {
  int ln;
  if (len < T.len)return 233;
  if (len == T.len){
    ln = len - 1;
    while (ln >= 0 && a[ln] == T.a[ln])--ln;
    if (ln >= 0 && a[ln] < T.a[ln])return 233;
    return 0;
  }
  return 0;
}
inline bool Big::operator < (const int &t)const{
  Big tee(t);
  return *this < tee;
}
inline void Big::print(){
  printf("%d",a[len - 1]);
  gd(i,len - 2,0){
    printf("%04d",a[i]);
  }
}

inline void print(Big s){
//s不要是引用，要不然你怎么print(a * b);
  int len = s.len;
  printf("%d",s.a[len - 1]);
  gd(i,len - 2,0){
    printf("%04d",s.a[i]);
  }
}
char s[100024];
```
