高精度

constexpr int MAXN = 9999;
// MAXN 是一位中最大的数字
constexpr int MAXSIZE = 10024;
// MAXSIZE 是位数
constexpr int DLEN = 4;

// DLEN 记录压几位
struct Big {
  int a[MAXSIZE], len;
  bool flag;  // 标记符号'-'

  Big() {
    len = 1;
    memset(a, 0, sizeof a);
    flag = false;
  }

  Big(const int);
  Big(const char*);
  Big(const Big&);
  Big& operator=(const Big&);
  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;
  void print() const;
};

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 = true;
  } else {
    t1 = *this;
    t2 = T;
    ctf = false;
  }
  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);
  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 true;
  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 true;
    return false;
  }
  return false;
}

bool Big::operator<(const int& t) const {
  Big tee(t);
  return *this < tee;
}

void Big::print() const {
  printf("%d", a[len - 1]);
  gd(i, len - 2, 0) { printf("%04d", a[i]); }
}

void print(const Big& s) {
  int len = s.len;
  printf("%d", s.a[len - 1]);
  gd(i, len - 2, 0) { printf("%04d", s.a[i]); }
}

char s[100024];

使用示例:

基本用法

1. 头文件包含和宏定义

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;

#define CLR(a) memset(a, 0, sizeof a)
#define f(i, a, b) for (int i = a; i < b; i++)
#define g(i, a, b) for (int i = a; i <= b; i++)
#define gd(i, a, b) for (int i = a; i >= b; i--)

2. 基本使用示例

int main() {
    // 从整数创建大数
    Big a(123456789);
    Big b(987654321);
    
    // 从字符串创建大数
    Big c("12345678901234567890");
    
    // 基本运算
    Big sum = a + b;
    Big diff = a - b;
    Big product = a * b;
    Big quotient = a / 123;  // 除以普通整数
    int remainder = a % 123; // 取模
    
    // 幂运算
    Big power = a ^ 3;  // a的3次方
    
    // 比较运算
    if (a < b) {
        cout << "a is smaller than b" << endl;
    }
    
    // 输出结果
    cout << "a = "; a.print(); cout << endl;
    cout << "b = "; b.print(); cout << endl;
    cout << "a + b = "; sum.print(); cout << endl;
    cout << "a - b = "; diff.print(); cout << endl;
    cout << "a * b = "; product.print(); cout << endl;
    
    return 0;
}

3. 更复杂的示例

// 计算阶乘
Big factorial(int n) {
    Big result(1);
    for (int i = 2; i <= n; i++) {
        result = result * Big(i);
    }
    return result;
}

// 计算斐波那契数列
Big fibonacci(int n) {
    if (n <= 1) return Big(n);
    Big a(0), b(1), c;
    for (int i = 2; i <= n; i++) {
        c = a + b;
        a = b;
        b = c;
    }
    return b;
}

int main() {
    // 计算大数阶乘
    Big fact = factorial(100);
    cout << "100! = "; fact.print(); cout << endl;
    
    // 计算大斐波那契数
    Big fib = fibonacci(100);
    cout << "fib(100) = "; fib.print(); cout << endl;
    
    // 从字符串读取大数
    char numStr[] = "123456789012345678901234567890";
    Big bigNum(numStr);
    cout << "Big number: "; bigNum.print(); cout << endl;
    
    return 0;
}

4. 处理用户输入

int main() {
    char s1[100024], s2[100024];
    
    cout << "Enter first big number: ";
    cin >> s1;
    cout << "Enter second big number: ";
    cin >> s2;
    
    Big a(s1), b(s2);
    
    cout << "a + b = "; (a + b).print(); cout << endl;
    cout << "a - b = "; (a - b).print(); cout << endl;
    cout << "a * b = "; (a * b).print(); cout << endl;
    
    return 0;
}

注意事项

  1. 压位存储:这个实现使用4位十进制数作为一个存储单元(DLEN=4)
  2. 内存分配:最大支持10024位数字,即约10000位十进制数
  3. 运算限制
    • 目前支持:加减乘、除以整数、幂运算(整数指数)
    • 不支持:大数除大数、大数的大数次方
  4. 性能:压位存储提高了运算效率

编译运行

确保使用C++11或更高版本编译:

g++ -std=c++11 -o bigint bigint.cpp
./bigint

这个类适合需要处理超出普通整数范围的大数运算场景,如密码学、大数计算、组合数学等应用。

posted @ 2025-11-14 20:23  miao-jc  阅读(3)  评论(0)    收藏  举报