Advertisement
Dang_Quan_10_Tin

Bignum

Feb 9th, 2022
737
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.84 KB | None | 0 0
  1. /// M là số chữ số ước lượng, nhớ thay đổi với các bài
  2. /// Nếu không có phép nhân thì nên đẩy BASE lên 1e17 hoặc 1e18
  3. /// a = Bignum(5) || a = Bignum("5") đều được, tuy nhiên khuyến khích dùng loại 1
  4. /// cin >> a hay a.read() đều được
  5. /// cout << a hay a.print() đều được, khuyến khích dùng loại 1
  6. /// Phép chia và phép mod chỉ dùng cho số nguyên và cho ra kết quả nguyên
  7.  
  8. using cd = complex<long double>;
  9. const long double PI = acos(-1);
  10. const int M = 2000;
  11. const ll BASE = 1e8;
  12. const int gd = log10(BASE);
  13. const int maxn = M / gd + 1;
  14. struct Bignum
  15. {
  16.     int n;
  17.     ll a[maxn];
  18.     Bignum(ll x = 0)
  19.     {
  20.         memset(a, 0, sizeof a);
  21.         n = 0;
  22.         do
  23.         {
  24.             a[n++] = x % BASE;
  25.             x /= BASE;
  26.         } while (x);
  27.     }
  28.     Bignum(const string &s)
  29.     {
  30.         Convert(s);
  31.     }
  32.     ll stoll(const string &s)
  33.     {
  34.         ll ans(0);
  35.         for (auto i : s)
  36.             ans = ans * 10 + i - '0';
  37.         return ans;
  38.     }
  39.     void Convert(const string &s)
  40.     {
  41.         memset(a, 0, sizeof a);
  42.         n = 0;
  43.         for (int i = s.size() - 1; ~i; --i)
  44.         {
  45.             int j = max(0, i - gd + 1);
  46.             a[n++] = stoll(s.substr(j, i - j + 1));
  47.             i = j;
  48.         }
  49.         fix();
  50.     }
  51.     void fix()
  52.     {
  53.         ++n;
  54.         for (int i = 0; i < n - 1; ++i)
  55.         {
  56.             a[i + 1] += a[i] / BASE;
  57.             a[i] %= BASE;
  58.             if (a[i] < 0)
  59.             {
  60.                 a[i] += BASE;
  61.                 --a[i + 1];
  62.             }
  63.         }
  64.         while (n > 1 && a[n - 1] == 0)
  65.             --n;
  66.     }
  67.     Bignum &operator+=(const Bignum &x)
  68.     {
  69.         n = max(n, x.n);
  70.         for (int i = 0; i < n; ++i)
  71.             a[i] += x.a[i];
  72.         fix();
  73.         return *this;
  74.     }
  75.     Bignum &operator-=(const Bignum &x)
  76.     {
  77.         for (int i = 0; i < x.n; ++i)
  78.             a[i] -= x.a[i];
  79.         fix();
  80.         return *this;
  81.     }
  82.     Bignum &operator*=(const Bignum &x)
  83.     {
  84.         vector<ll> c(x.n + n, 0);
  85.  
  86.         for (int i = 0; i < n; ++i)
  87.             for (int j = 0; j < x.n; ++j)
  88.                 c[i + j] += a[i] * x.a[j];
  89.  
  90.         n += x.n;
  91.         for (int i = 0; i < n; ++i)
  92.             a[i] = c[i];
  93.  
  94.         fix();
  95.         return *this;
  96.     }
  97.     Bignum &operator/=(const ll &x)
  98.     {
  99.         ll r = 0ll;
  100.         for (int i = n - 1; i > -1; --i)
  101.         {
  102.             r = r * BASE + a[i];
  103.             a[i] = r / x;
  104.             r %= x;
  105.         }
  106.         fix();
  107.         return *this;
  108.     }
  109.     Bignum operator+(const Bignum &s)
  110.     {
  111.         Bignum c;
  112.         copy(a, a + n, c.a);
  113.         c.n = n;
  114.         c += s;
  115.         return c;
  116.     }
  117.     Bignum operator-(const Bignum &s)
  118.     {
  119.         Bignum c;
  120.         copy(a, a + n, c.a);
  121.         c.n = n;
  122.         c -= s;
  123.         return c;
  124.     }
  125.     Bignum operator*(const Bignum &s)
  126.     {
  127.         Bignum c;
  128.         copy(a, a + n, c.a);
  129.         c.n = n;
  130.         c *= s;
  131.         return c;
  132.     }
  133.     Bignum operator/(const ll &x)
  134.     {
  135.         Bignum c;
  136.         copy(a, a + n, c.a);
  137.         c.n = n;
  138.         c /= x;
  139.         return c;
  140.     }
  141.     ll operator%(const ll &x)
  142.     {
  143.         ll ans(0);
  144.         for (int i = n - 1; ~i; --i)
  145.             ans = (ans * BASE + a[i]) % x;
  146.         return ans;
  147.     }
  148.     int com(const Bignum &s) const
  149.     {
  150.         if (n < s.n)
  151.             return 1;
  152.         if (n > s.n)
  153.             return 2;
  154.         for (int i = n - 1; i > -1; --i)
  155.             if (a[i] > s.a[i])
  156.                 return 2;
  157.             else if (a[i] < s.a[i])
  158.                 return 1;
  159.         return 3;
  160.     }
  161.     bool operator<(const Bignum &s) const
  162.     {
  163.         return com(s) == 1;
  164.     }
  165.     bool operator>(const Bignum &s) const
  166.     {
  167.         return com(s) == 2;
  168.     }
  169.     bool operator==(const Bignum &s) const
  170.     {
  171.         return com(s) == 3;
  172.     }
  173.     bool operator<=(const Bignum &s) const
  174.     {
  175.         return com(s) != 2;
  176.     }
  177.     bool operator>=(const Bignum &s) const
  178.     {
  179.         return com(s) != 1;
  180.     }
  181.     void read()
  182.     {
  183.         string s;
  184.         cin >> s;
  185.         Convert(s);
  186.     }
  187.     void print()
  188.     {
  189.         int i = n;
  190.         while (i > 0 && a[i] == 0)
  191.             --i;
  192.         cout << a[i];
  193.         for (--i; ~i; --i)
  194.             cout << setw(gd) << setfill('0') << a[i];
  195.     }
  196.     friend istream &operator>>(istream &in, Bignum &x)
  197.     {
  198.         string s;
  199.         in >> s;
  200.         x.Convert(s);
  201.         return in;
  202.     }
  203.     friend ostream &operator<<(ostream &out, const Bignum &x)
  204.     {
  205.         int i = x.n;
  206.         while (i > 0 && x.a[i] == 0)
  207.             --i;
  208.         out << x.a[i];
  209.         for (--i; ~i; --i)
  210.             out << setw(gd) << setfill('0') << x.a[i];
  211.         return out;
  212.     }
  213. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement