Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- typedef __int128 ll;
- typedef long double ld;
- const int D = 10;
- const ll T = 1e16, Q = 16, K = 10;
- void printd(ll k)
- {
- vector<int> a;
- for (int i = 0; i < Q; i++)
- {
- a.push_back(k % K);
- k /= K;
- }
- for (int i = Q - 1; i >= 0; i--)
- cout << a[i];
- }
- struct Double
- {
- int sgn;
- vector<ll> dig;
- int st;
- Double()
- {
- sgn = 0;
- }
- void rem()
- {
- while (dig.size() < D)
- dig.push_back(0);
- while (dig.size() > D)
- dig.pop_back();
- for (int i = D - 1; i > 0; i--)
- {
- dig[i - 1] += dig[i] / T;
- dig[i] %= T;
- }
- reverse(dig.begin(), dig.end());
- while (dig.back() >= T)
- {
- int z = dig.size() - 1;
- dig.push_back(dig[z] / T);
- dig[z] %= T;
- }
- while (dig.size() && !dig.back())
- dig.pop_back(), st--;
- if (!dig.size())
- {
- sgn = 0;
- while (dig.size() < D)
- dig.push_back(0);
- return;
- }
- reverse(dig.begin(), dig.end());
- while (dig.size() < D)
- dig.push_back(0);
- while (dig.size() > D)
- dig.pop_back();
- }
- Double(ll p, ll q = 1)
- {
- if (p == 0)
- {
- sgn = 0;
- dig.assign(D, 0);
- st = 1;
- return;
- }
- sgn = 1;
- if (p < 0)
- {
- p = -p;
- q = -q;
- }
- if (q < 0)
- {
- sgn = -1;
- q = -q;
- }
- ll t = p / q;
- ll a = p % q;
- while (t)
- {
- dig.push_back(t % T);
- t /= T;
- }
- reverse(dig.begin(), dig.end());
- st = dig.size() - 1;
- a *= T;
- ll b = q;
- while (dig.size() < D)
- {
- dig.push_back(a % b);
- a /= b;
- a *= T;
- }
- (*this).rem();
- }
- void print()
- {
- (*this).rem();
- if (sgn == 0)
- {
- cout << "0\n";
- return;
- }
- if (sgn == -1)
- cout << "-";
- if (st < 0)
- {
- cout << "0.";
- for (int i = 1; i < abs(st); i++)
- for (int j = 0; j < Q; j++)
- cout << 0;
- for (ll i : dig)
- printd(i);//cout << i;
- cout << '\n';
- return;
- }
- if (st + 1 >= dig.size())
- {
- bool ok = 0;
- for (ll i : dig)
- {
- if (ok)
- printd(i);//cout << i;
- else
- cout << (long long)i;
- ok = 1;
- }
- for (int i = 0; i <= st - dig.size(); i++)
- for (int j = 0; j < Q; j++)
- cout << 0;
- cout << '\n';
- return;
- }
- for (int i = 0; i <= st; i++)
- if (i)
- printd(dig[i]);//cout << dig[i];
- else
- cout << (long long)dig[i];
- cout << ".";
- for (int i = st + 1; i < dig.size(); i++)
- printd(dig[i]);//cout << dig[i];
- cout << '\n';
- }
- Double operator*(const Double &x) const
- {
- if (sgn == 0)
- return *this;
- if (x.sgn == 0)
- return x;
- Double ans;
- ans.sgn = sgn * x.sgn;
- ans.dig.assign(2 * D, 0);
- ans.st = st + x.st + 1;
- for (int i = 0; i < D; i++)
- for (int j = 0; j < D; j++)
- ans.dig[i + j + 1] += dig[i] * x.dig[j];
- for (int i = 2 * D - 1; i > 0; i--)
- if (ans.dig[i] >= T)
- {
- ans.dig[i - 1] += ans.dig[i] / T;
- ans.dig[i] %= T;
- }
- while (ans.dig.size() > D)
- ans.dig.pop_back();
- ans.rem();
- return ans;
- }
- bool operator==(const Double &x) const
- {
- if (sgn == 0)
- return x.sgn == 0;
- return (sgn == x.sgn && x.dig == dig && st == x.st);
- }
- bool operator!=(const Double &x) const
- {
- if (sgn == 0 && x.sgn == 0)
- return 0;
- return (sgn != x.sgn || x.dig != dig || st != x.st);
- }
- bool operator>(const Double &x) const
- {
- if (sgn != x.sgn)
- return sgn > x.sgn;
- if (sgn == 0)
- return 0;
- if (st != x.st)
- return ((st > x.st) ^ (sgn == -1));
- for (int i = 0; i < D; i++)
- if (dig[i] != x.dig[i])
- return ((sgn == -1) ^ (dig[i] > x.dig[i]));
- return 0;
- }
- bool operator<(const Double &x) const
- {
- if (sgn != x.sgn)
- return sgn < x.sgn;
- if (sgn == 0)
- return 0;
- if (st != x.st)
- return ((st < x.st) ^ (sgn == -1));
- for (int i = 0; i < D; i++)
- if (dig[i] != x.dig[i])
- return ((sgn == -1) ^ (dig[i] < x.dig[i]));
- return 0;
- }
- bool operator>=(const Double &x) const
- {
- return (*this) > x || (*this) == x;
- if (sgn != x.sgn)
- return sgn > x.sgn;
- if (sgn == 0)
- return 1;
- if (st != x.st)
- return ((st > x.st) ^ (sgn == -1));
- for (int i = 0; i < D; i++)
- if (dig[i] != x.dig[i])
- return ((sgn == -1) ^ (dig[i] > x.dig[i]));
- return 1;
- }
- bool operator<=(const Double &x) const
- {
- return (*this) < x || (*this) == x;
- if (sgn != x.sgn)
- return sgn < x.sgn;
- if (sgn == 0)
- return 1;
- if (st != x.st)
- return ((st < x.st) ^ (sgn == -1));
- for (int i = 0; i < D; i++)
- if (dig[i] != x.dig[i])
- return ((sgn == -1) ^ (dig[i] < x.dig[i]));
- return 1;
- }
- Double operator-() const
- {
- Double ans = *this;
- ans.sgn = -ans.sgn;
- return ans;
- }
- Double operator-(Double x)
- {
- if (x.sgn == 0)
- return (*this);
- if (sgn == 0)
- return -x;
- if (sgn != x.sgn)
- return (*this) + (-x);
- if (sgn == -1)
- return (-x) - (-(*this));
- if (x == (*this))
- {
- Double y = x;
- y.sgn = 0;
- return y;
- }
- Double a = (*this), b = x;
- bool cmp = (a > b);
- if (!cmp)
- swap(a, b);
- Double ans;
- reverse(a.dig.begin(), a.dig.end());
- reverse(b.dig.begin(), b.dig.end());
- while (a.st < b.st)
- {
- a.dig.push_back(0);
- a.st++;
- }
- while (a.st > b.st)
- {
- b.dig.push_back(0);
- b.st++;
- }
- reverse(a.dig.begin(), a.dig.end());
- reverse(b.dig.begin(), b.dig.end());
- while (a.dig.size() > D)
- a.dig.pop_back();
- while (b.dig.size() > D)
- b.dig.pop_back();
- ans.dig.assign(D, 0);
- ans.st = a.st;
- for (int i = 0; i < D; i++)
- ans.dig[i] = a.dig[i] - b.dig[i];
- for (int i = D - 1; i > 0; i--)
- while (ans.dig[i] < 0)
- {
- ans.dig[i] += T;
- ans.dig[i - 1]--;
- }
- ans.sgn = (cmp ? 1 : -1);
- ans.rem();
- return ans;
- }
- Double operator+(Double x)
- {
- if (sgn == 0)
- return x;
- if (x.sgn == 0)
- return *this;
- if (sgn != x.sgn)
- {
- return (*this) - (-x);
- }
- vector<ll> dig1 = dig;
- int St = st;
- reverse(dig1.begin(), dig1.end());
- reverse(x.dig.begin(), x.dig.end());
- while (St < x.st)
- {
- dig1.push_back(0);
- St++;
- }
- while (St > x.st)
- {
- x.dig.push_back(0);
- x.st++;
- }
- reverse(dig1.begin(), dig1.end());
- reverse(x.dig.begin(), x.dig.end());
- while (dig1.size() > D)
- dig1.pop_back();
- while (x.dig.size() > D)
- x.dig.pop_back();
- Double ans;
- ans.sgn = x.sgn;
- ans.dig.assign(D + 1, 0);
- ans.st = St + 1;
- for (int i = 0; i < D; i++)
- ans.dig[i + 1] = dig1[i] + x.dig[i];
- ans.rem();
- return ans;
- }
- Double rev() const
- {
- if (sgn == 0)
- {
- cerr << "DIVIDING BY ZERO\n";
- exit(0);
- }
- Double x = (*this);
- x.sgn = 1;
- Double div(1);
- Double ans;
- ans.sgn = sgn;
- ans.dig.clear();
- ans.st = 1;
- while (x < Double(1))
- {
- x.st++;
- ans.st++;
- }
- while (div < x)
- div.st++;
- ans.st -= div.st + 1;
- while (ans.dig.size() < D)
- {
- ll nxt = 0;
- ll l = 0, r = T;/*
- while (div >= x)
- {
- div = div - x;
- nxt++;
- }*/
- while (r - l > 1)
- {
- ll mid = (r + l) / 2;
- if (x * Double(mid) > div)
- r = mid;
- else
- l = mid;
- }
- div = div - x * Double(l);
- nxt = l;
- div.st++;
- ans.dig.push_back(nxt);
- }
- ans.rem();
- /* cout << ans.sgn << endl;
- cout << ans.st << endl;
- cout << ans.dig.size() << endl;
- for (int i : ans.dig)
- cout << i << ' ';
- cout << endl;
- exit(0);*/
- return ans;
- }
- Double operator/(const Double &x) const
- {
- return (*this) * x.rev();
- }
- Double operator*(const int &x) const
- {
- return (*this) * Double(x);
- }
- Double operator/(const int &x) const
- {
- return (*this) / Double(x);
- }
- };
- Double Sqrt(ll x)
- {
- if (x <= 0)
- return 0;
- ll t = sqrt(x);
- Double ans(t);
- for (int i = 0; i < ans.dig.size(); i++)
- ans.dig[i] = 0;
- Double X = x;
- for (int i = 0; i < D; i++)
- {
- ll l = 0, r = T;
- while (r - l > 1)
- {
- ll mid = (r + l) / 2;
- ans.dig[i] = mid;
- if (ans * ans > X)
- r = mid;
- else
- l = mid;
- }
- ans.dig[i] = l;
- }
- return ans;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement