#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <cctype>
#include <cmath>
#include <sstream>
#include <stdexcept>
using namespace std;
class HighPrecisionInt {
private:
vector<int> digits;
bool isNegative;
void removeLeadingZeros() {
while (digits.size() > 1 && digits.back() == 0) {
digits.pop_back();
}
if (digits.size() == 1 && digits[0] == 0) {
isNegative = false;
}
}
HighPrecisionInt absolute() const {
HighPrecisionInt res = *this;
res.isNegative = false;
return res;
}
public:
HighPrecisionInt() : isNegative(false) {
digits.push_back(0);
}
HighPrecisionInt(const string& numStr) : isNegative(false) {
size_t start = 0;
if (numStr.empty()) {
digits.push_back(0);
return;
}
if (numStr[0] == '-') {
isNegative = true;
start = 1;
} else if (numStr[0] == '+') {
start = 1;
}
for (size_t i = numStr.size() - 1; i >= start; --i) {
if (!isdigit(numStr[i])) {
throw invalid_argument("Invalid integer string");
}
digits.push_back(numStr[i] - '0');
}
removeLeadingZeros();
}
HighPrecisionInt(long long num) : isNegative(false) {
if (num < 0) {
isNegative = true;
num = -num;
}
if (num == 0) {
digits.push_back(0);
return;
}
while (num > 0) {
digits.push_back(num % 10);
num /= 10;
}
}
string toString() const {
if (digits.empty()) return "0";
string res;
if (isNegative) res += '-';
for (auto it = digits.rbegin(); it != digits.rend(); ++it) {
res += char('0' + *it);
}
return res.empty() ? "0" : res;
}
HighPrecisionInt operator+(const HighPrecisionInt& other) const {
HighPrecisionInt result;
if (isNegative == other.isNegative) {
result.isNegative = isNegative;
int carry = 0;
size_t i = 0;
while (i < digits.size() || i < other.digits.size() || carry) {
int sum = carry;
if (i < digits.size()) sum += digits[i];
if (i < other.digits.size()) sum += other.digits[i];
carry = sum / 10;
result.digits.push_back(sum % 10);
++i;
}
} else {
if (absolute() >= other.absolute()) {
result.isNegative = isNegative;
int borrow = 0;
size_t i = 0;
while (i < digits.size() || i < other.digits.size()) {
int diff = borrow;
if (i < digits.size()) diff += digits[i];
if (i < other.digits.size()) diff -= other.digits[i];
if (diff < 0) {
diff += 10;
borrow = -1;
} else {
borrow = 0;
}
result.digits.push_back(diff);
++i;
}
} else {
result.isNegative = other.isNegative;
int borrow = 0;
size_t i = 0;
while (i < digits.size() || i < other.digits.size()) {
int diff = borrow;
if (i < other.digits.size()) diff += other.digits[i];
if (i < digits.size()) diff -= digits[i];
if (diff < 0) {
diff += 10;
borrow = -1;
} else {
borrow = 0;
}
result.digits.push_back(diff);
++i;
}
}
}
result.removeLeadingZeros();
return result;
}
HighPrecisionInt operator-(const HighPrecisionInt& other) const {
HighPrecisionInt temp = other;
temp.isNegative = !temp.isNegative;
return *this + temp;
}
HighPrecisionInt operator*(const HighPrecisionInt& other) const {
HighPrecisionInt result;
result.digits.resize(digits.size() + other.digits.size(), 0);
result.isNegative = isNegative != other.isNegative;
for (size_t i = 0; i < digits.size(); ++i) {
int carry = 0;
for (size_t j = 0; j < other.digits.size() || carry; ++j) {
long long product = result.digits[i + j] + carry;
if (j < other.digits.size()) {
product += (long long)digits[i] * other.digits[j];
}
result.digits[i + j] = product % 10;
carry = product / 10;
}
}
result.removeLeadingZeros();
return result;
}
HighPrecisionInt operator/(const HighPrecisionInt& other) const {
if (other.isZero()) {
throw runtime_error("Division by zero");
}
HighPrecisionInt dividend = absolute();
HighPrecisionInt divisor = other.absolute();
HighPrecisionInt quotient;
HighPrecisionInt remainder;
if (dividend < divisor) {
return HighPrecisionInt(0);
}
quotient.digits.reserve(dividend.digits.size());
size_t i = dividend.digits.size();
while (i > 0) {
--i;
remainder = remainder * HighPrecisionInt(10) + HighPrecisionInt(dividend.digits[i]);
int count = 0;
while (remainder >= divisor) {
remainder = remainder - divisor;
++count;
}
quotient.digits.push_back(count);
}
reverse(quotient.digits.begin(), quotient.digits.end());
quotient.isNegative = isNegative != other.isNegative;
quotient.removeLeadingZeros();
return quotient;
}
HighPrecisionInt operator%(const HighPrecisionInt& other) const {
if (other.isZero()) {
throw runtime_error("Modulo by zero");
}
HighPrecisionInt dividend = absolute();
HighPrecisionInt divisor = other.absolute();
HighPrecisionInt remainder;
if (dividend < divisor) {
remainder = dividend;
} else {
size_t i = dividend.digits.size();
while (i > 0) {
--i;
remainder = remainder * HighPrecisionInt(10) + HighPrecisionInt(dividend.digits[i]);
while (remainder >= divisor) {
remainder = remainder - divisor;
}
}
}
remainder.isNegative = isNegative;
remainder.removeLeadingZeros();
return remainder;
}
HighPrecisionInt& operator+=(const HighPrecisionInt& other) {
*this = *this + other;
return *this;
}
HighPrecisionInt& operator-=(const HighPrecisionInt& other) {
*this = *this - other;
return *this;
}
HighPrecisionInt& operator*=(const HighPrecisionInt& other) {
*this = *this * other;
return *this;
}
HighPrecisionInt& operator/=(const HighPrecisionInt& other) {
*this = *this / other;
return *this;
}
HighPrecisionInt& operator%=(const HighPrecisionInt& other) {
*this = *this % other;
return *this;
}
HighPrecisionInt operator-() const {
HighPrecisionInt res = *this;
if (!res.isZero()) {
res.isNegative = !res.isNegative;
}
return res;
}
HighPrecisionInt operator++() {
*this += HighPrecisionInt(1);
return *this;
}
HighPrecisionInt operator++(int) {
HighPrecisionInt temp = *this;
*this += HighPrecisionInt(1);
return temp;
}
HighPrecisionInt operator--() {
*this -= HighPrecisionInt(1);
return *this;
}
HighPrecisionInt operator--(int) {
HighPrecisionInt temp = *this;
*this -= HighPrecisionInt(1);
return temp;
}
bool operator==(const HighPrecisionInt& other) const {
if (isNegative != other.isNegative) return false;
if (digits.size() != other.digits.size()) return false;
for (size_t i = 0; i < digits.size(); ++i) {
if (digits[i] != other.digits[i]) return false;
}
return true;
}
bool operator!=(const HighPrecisionInt& other) const {
return !(*this == other);
}
bool operator>(const HighPrecisionInt& other) const {
if (isNegative != other.isNegative) {
return !isNegative;
}
if (isNegative) {
return absolute() < other.absolute();
} else {
if (digits.size() != other.digits.size()) {
return digits.size() > other.digits.size();
}
for (size_t i = digits.size(); i > 0; --i) {
if (digits[i - 1] != other.digits[i - 1]) {
return digits[i - 1] > other.digits[i - 1];
}
}
return false;
}
}
bool operator<(const HighPrecisionInt& other) const {
return other > *this;
}
bool operator>=(const HighPrecisionInt& other) const {
return !(*this < other);
}
bool operator<=(const HighPrecisionInt& other) const {
return !(*this > other);
}
bool isZero() const {
return digits.size() == 1 && digits[0] == 0 && !isNegative;
}
HighPrecisionInt pow(const HighPrecisionInt& exponent) const {
if (exponent.isNegative()) {
throw invalid_argument("Exponent cannot be negative");
}
if (exponent.isZero()) {
return HighPrecisionInt(1);
}
if (*this == HighPrecisionInt(0)) {
return HighPrecisionInt(0);
}
HighPrecisionInt result(1);
HighPrecisionInt base = *this;
HighPrecisionInt exp = exponent;
while (exp > HighPrecisionInt(0)) {
if (exp % HighPrecisionInt(2) == HighPrecisionInt(1)) {
result *= base;
}
base *= base;
exp /= HighPrecisionInt(2);
}
return result;
}
HighPrecisionInt gcd(const HighPrecisionInt& other) const {
HighPrecisionInt a = absolute();
HighPrecisionInt b = other.absolute();
while (!b.isZero()) {
HighPrecisionInt temp = b;
b = a % b;
a = temp;
}
return a;
}
HighPrecisionInt lcm(const HighPrecisionInt& other) const {
if (isZero() || other.isZero()) {
return HighPrecisionInt(0);
}
return (*this * other).absolute() / gcd(other);
}
bool isNegative() const {
return isNegative;
}
size_t length() const {
return digits.size();
}
HighPrecisionInt factorial() const {
if (isNegative()) {
throw invalid_argument("Factorial of negative number is undefined");
}
HighPrecisionInt result(1);
HighPrecisionInt num = *this;
while (num > HighPrecisionInt(0)) {
result *= num;
--num;
}
return result;
}
vector<int> getDigits() const {
return digits;
}
friend ostream& operator<<(ostream& os, const HighPrecisionInt& num) {
os << num.toString();
return os;
}
friend istream& operator>>(istream& is, HighPrecisionInt& num) {
string s;
is >> s;
num = HighPrecisionInt(s);
return is;
}
};
class HighPrecisionDecimal {
private:
HighPrecisionInt integerPart;
vector<int> fractionalPart;
size_t precision;
void removeTrailingZeros() {
while (fractionalPart.size() > 0 && fractionalPart.back() == 0) {
fractionalPart.pop_back();
}
if (fractionalPart.empty() && integerPart.isZero()) {
fractionalPart.push_back(0);
}
if (precision > 0 && fractionalPart.size() > precision) {
roundToPrecision(precision);
}
}
void roundToPrecision(size_t prec) {
if (fractionalPart.size() <= prec) {
while (fractionalPart.size() < prec) {
fractionalPart.push_back(0);
}
return;
}
int carry = fractionalPart[prec] >= 5 ? 1 : 0;
fractionalPart.resize(prec);
if (carry > 0) {
HighPrecisionInt temp(1);
integerPart += temp;
}
removeTrailingZeros();
}
public:
HighPrecisionDecimal(size_t prec = 100) : precision(prec) {
fractionalPart.push_back(0);
}
HighPrecisionDecimal(const string& numStr, size_t prec = 100) : precision(prec) {
size_t dotPos = numStr.find('.');
string intStr, fracStr;
if (dotPos == string::npos) {
intStr = numStr;
fracStr = "";
} else {
intStr = numStr.substr(0, dotPos);
fracStr = numStr.substr(dotPos + 1);
}
integerPart = HighPrecisionInt(intStr);
for (char c : fracStr) {
if (!isdigit(c)) {
throw invalid_argument("Invalid decimal string");
}
fractionalPart.push_back(c - '0');
}
removeTrailingZeros();
if (fractionalPart.size() > precision) {
roundToPrecision(precision);
}
}
HighPrecisionDecimal(long long num, size_t prec = 100) : integerPart(num), precision(prec) {
fractionalPart.push_back(0);
}
HighPrecisionDecimal(const HighPrecisionInt& intPart, size_t prec = 100) : integerPart(intPart), precision(prec) {
fractionalPart.push_back(0);
}
string toString() const {
string res = integerPart.toString();
if (!fractionalPart.empty() && !(fractionalPart.size() == 1 && fractionalPart[0] == 0)) {
res += '.';
for (auto it = fractionalPart.rbegin(); it != fractionalPart.rend(); ++it) {
res += char('0' + *it);
}
}
return res;
}
string toScientificNotation() const {
string intStr = integerPart.toString();
bool isNeg = integerPart.isNegative();
string absIntStr = isNeg ? intStr.substr(1) : intStr;
string sigFigs;
size_t exp;
if (absIntStr == "0") {
size_t firstNonZero = 0;
while (firstNonZero < fractionalPart.size() && fractionalPart[firstNonZero] == 0) {
++firstNonZero;
}
if (firstNonZero == fractionalPart.size()) {
return "0e0";
}
sigFigs += char('0' + fractionalPart[firstNonZero]);
sigFigs += '.';
for (size_t i = firstNonZero + 1; i < fractionalPart.size() && i < firstNonZero + 1 + precision; ++i) {
sigFigs += char('0' + fractionalPart[i]);
}
exp = -(firstNonZero + 1);
} else {
sigFigs += absIntStr[0];
if (absIntStr.size() > 1) {
sigFigs += '.';
sigFigs += absIntStr.substr(1);
}
for (size_t i = 0; i < fractionalPart.size() && sigFigs.size() - (absIntStr.size() > 1 ? 2 : 1) < precision; ++i) {
sigFigs += char('0' + fractionalPart[i]);
}
exp = absIntStr.size() - 1;
}
string res;
if (isNeg) res += '-';
res += sigFigs;
res += 'e';
res += to_string(exp);
return res;
}
HighPrecisionDecimal operator+(const HighPrecisionDecimal& other) const {
HighPrecisionDecimal result(precision > other.precision ? precision : other.precision);
size_t maxFracSize = max(fractionalPart.size(), other.fractionalPart.size());
vector<int> tempFrac(maxFracSize + 1, 0);
int carry = 0;
for (size_t i = 0; i < maxFracSize; ++i) {
int sum = carry;
if (i < fractionalPart.size()) sum += fractionalPart[i];
if (i < other.fractionalPart.size()) sum += other.fractionalPart[i];
tempFrac[i] = sum % 10;
carry = sum / 10;
}
result.integerPart = integerPart + other.integerPart + HighPrecisionInt(carry);
result.fractionalPart.clear();
for (size_t i = 0; i < maxFracSize; ++i) {
result.fractionalPart.push_back(tempFrac[i]);
}
result.removeTrailingZeros();
return result;
}
HighPrecisionDecimal operator-(const HighPrecisionDecimal& other) const {
HighPrecisionDecimal temp = other;
temp.integerPart = -temp.integerPart;
return *this + temp;
}
HighPrecisionDecimal operator*(const HighPrecisionDecimal& other) const {
size_t newPrecision = precision + other.precision;
HighPrecisionDecimal result(newPrecision);
HighPrecisionInt intProduct = integerPart * other.integerPart;
HighPrecisionInt fracInt1(0);
for (auto it = fractionalPart.rbegin(); it != fractionalPart.rend(); ++it) {
fracInt1 = fracInt1 * HighPrecisionInt(10) + HighPrecisionInt(*it);
}
HighPrecisionInt fracInt2(0);
for (auto it = other.fractionalPart.rbegin(); it != other.fractionalPart.rend(); ++it) {
fracInt2 = fracInt2 * HighPrecisionInt(10) + HighPrecisionInt(*it);
}
HighPrecisionInt fracProduct = fracInt1 * fracInt2;
string fracProdStr = fracProduct.toString();
size_t totalFracDigits = fractionalPart.size() + other.fractionalPart.size();
while (fracProdStr.size() < totalFracDigits) {
fracProdStr = "0" + fracProdStr;
}
string newIntStr, newFracStr;
if (fracProdStr.size() > totalFracDigits) {
newIntStr = fracProdStr.substr(0, fracProdStr.size() - totalFracDigits);
newFracStr = fracProdStr.substr(fracProdStr.size() - totalFracDigits);
} else {
newIntStr = "0";
newFracStr = fracProdStr;
}
HighPrecisionInt cross1 = integerPart * fracInt2;
HighPrecisionInt cross2 = other.integerPart * fracInt1;
HighPrecisionInt crossSum = cross1 + cross2;
string crossSumStr = crossSum.toString();
if (crossSumStr.size() > other.fractionalPart.size()) {
newIntStr = (HighPrecisionInt(newIntStr) + HighPrecisionInt(crossSumStr.substr(0, crossSumStr.size() - other.fractionalPart.size()))).toString();
newFracStr = crossSumStr.substr(crossSumStr.size() - other.fractionalPart.size()) + newFracStr;
} else {
while (crossSumStr.size() < other.fractionalPart.size()) {
crossSumStr = "0" + crossSumStr;
}
newFracStr = crossSumStr + newFracStr;
}
result.integerPart = intProduct + HighPrecisionInt(newIntStr);
result.fractionalPart.clear();
for (size_t i = newFracStr.size(); i > 0; --i) {
result.fractionalPart.push_back(newFracStr[i - 1] - '0');
}
result.removeTrailingZeros();
return result;
}
HighPrecisionDecimal operator/(const HighPrecisionDecimal& other) const {
if (other.isZero()) {
throw runtime_error("Division by zero");
}
HighPrecisionDecimal dividend = *this;
HighPrecisionDecimal divisor = other;
HighPrecisionInt dividendInt = dividend.integerPart;
HighPrecisionInt divisorInt = divisor.integerPart;
size_t shift = 0;
while (divisorInt.isZero() || (dividendInt < divisorInt && !dividendInt.isZero())) {
divisor.shiftLeft(1);
shift++;
divisorInt = divisor.integerPart;
}
HighPrecisionDecimal quotient(precision);
HighPrecisionDecimal remainder(precision);
HighPrecisionInt currentInt = dividendInt;
vector<int> currentFrac = dividend.fractionalPart;
for (size_t i = 0; i <= precision; ++i) {
int digit = 0;
while (currentInt > divisorInt || (currentInt == divisorInt && remainder.isZero())) {
currentInt -= divisorInt;
digit++;
}
if (i < precision) {
quotient.fractionalPart.push_back(digit);
}
if (i < currentFrac.size()) {
currentInt = currentInt * HighPrecisionInt(10) + HighPrecisionInt(currentFrac[i]);
} else {
currentInt = currentInt * HighPrecisionInt(10);
}
}
reverse(quotient.fractionalPart.begin(), quotient.fractionalPart.end());
quotient.integerPart = HighPrecisionInt(0);
quotient.removeTrailingZeros();
for (size_t i = 0; i < shift; ++i) {
quotient.shiftRight(1);
}
return quotient;
}
HighPrecisionDecimal& operator+=(const HighPrecisionDecimal& other) {
*this = *this + other;
return *this;
}
HighPrecisionDecimal& operator-=(const HighPrecisionDecimal& other) {
*this = *this - other;
return *this;
}
HighPrecisionDecimal& operator*=(const HighPrecisionDecimal& other) {
*this = *this * other;
return *this;
}
HighPrecisionDecimal& operator/=(const HighPrecisionDecimal& other) {
*this = *this / other;
return *this;
}
HighPrecisionDecimal operator-() const {
HighPrecisionDecimal res = *this;
res.integerPart = -res.integerPart;
return res;
}
bool operator==(const HighPrecisionDecimal& other) const {
if (integerPart != other.integerPart) return false;
size_t maxFracSize = max(fractionalPart.size(), other.fractionalPart.size());
for (size_t i = 0; i < maxFracSize; ++i) {
int d1 = (i < fractionalPart.size()) ? fractionalPart[i] : 0;
int d2 = (i < other.fractionalPart.size()) ? other.fractionalPart[i] : 0;
if (d1 != d2) return false;
}
return true;
}
bool operator!=(const HighPrecisionDecimal& other) const {
return !(*this == other);
}
bool operator>(const HighPrecisionDecimal& other) const {
if (integerPart != other.integerPart) {
return integerPart > other.integerPart;
}
size_t maxFracSize = max(fractionalPart.size(), other.fractionalPart.size());
for (size_t i = 0; i < maxFracSize; ++i) {
int d1 = (i < fractionalPart.size()) ? fractionalPart[i] : 0;
int d2 = (i < other.fractionalPart.size()) ? other.fractionalPart[i] : 0;
if (d1 != d2) {
return d1 > d2;
}
}
return false;
}
bool operator<(const HighPrecisionDecimal& other) const {
return other > *this;
}
bool operator>=(const HighPrecisionDecimal& other) const {
return !(*this < other);
}
bool operator<=(const HighPrecisionDecimal& other) const {
return !(*this > other);
}
bool isZero() const {
return integerPart.isZero() && fractionalPart.size() == 1 && fractionalPart[0] == 0;
}
void setPrecision(size_t prec) {
precision = prec;
removeTrailingZeros();
}
size_t getPrecision() const {
return precision;
}
HighPrecisionInt getIntegerPart() const {
return integerPart;
}
vector<int> getFractionalPart() const {
return fractionalPart;
}
HighPrecisionDecimal pow(const HighPrecisionInt& exponent) const {
if (exponent.isNegative()) {
HighPrecisionDecimal one("1", precision);
return one / pow(-exponent);
}
HighPrecisionDecimal result("1", precision);
HighPrecisionDecimal base = *this;
HighPrecisionInt exp = exponent;
while (exp > HighPrecisionInt(0)) {
if (exp % HighPrecisionInt(2) == HighPrecisionInt(1)) {
result *= base;
}
base *= base;
exp /= HighPrecisionInt(2);
}
return result;
}
HighPrecisionDecimal sqrt() const {
if (integerPart.isNegative()) {
throw invalid_argument("Square root of negative number is undefined");
}
if (isZero()) {
return HighPrecisionDecimal("0", precision);
}
HighPrecisionDecimal low("0", precision);
HighPrecisionDecimal high = *this;
if (high < HighPrecisionDecimal("1", precision)) {
high = HighPrecisionDecimal("1", precision);
}
HighPrecisionDecimal eps("1", precision);
eps = eps.pow(HighPrecisionInt(precision + 1));
for (size_t i = 0; i < precision * 2; ++i) {
HighPrecisionDecimal mid = (low + high) / HighPrecisionDecimal("2", precision);
HighPrecisionDecimal midSq = mid * mid;
if (midSq > *this) {
high = mid;
} else {
low = mid;
}
if (high - low < eps) {
break;
}
}
return (low + high) / HighPrecisionDecimal("2", precision);
}
void shiftLeft(size_t n) {
for (size_t i = 0; i < n; ++i) {
if (!fractionalPart.empty()) {
integerPart = integerPart * HighPrecisionInt(10) + HighPrecisionInt(fractionalPart.back());
fractionalPart.pop_back();
} else {
integerPart = integerPart * HighPrecisionInt(10);
}
}
removeTrailingZeros();
}
void shiftRight(size_t n) {
for (size_t i = 0; i < n; ++i) {
fractionalPart.push_back(integerPart % HighPrecisionInt(10).getDigits()[0]);
integerPart /= HighPrecisionInt(10);
}
removeTrailingZeros();
}
friend ostream& operator<<(ostream& os, const HighPrecisionDecimal& num) {
os << num.toString();
return os;
}
friend istream& operator>>(istream& is, HighPrecisionDecimal& num) {
string s;
is >> s;
num = HighPrecisionDecimal(s, num.precision);
return is;
}
};
HighPrecisionInt factorialSeriesSum(const HighPrecisionInt& n) {
HighPrecisionInt sum(0);
HighPrecisionInt current(1);
for (HighPrecisionInt i(0); i <= n; ++i) {
sum += current;
if (i < n) {
current *= (i + HighPrecisionInt(1));
}
}
return sum;
}
HighPrecisionDecimal pi(size_t precision) {
HighPrecisionDecimal result("0", precision);
HighPrecisionDecimal sign("1", precision);
HighPrecisionDecimal denominator("1", precision);
HighPrecisionDecimal four("4", precision);
for (size_t i = 0; i < precision * 2; ++i) {
result += sign * four / denominator;
sign = -sign;
denominator += HighPrecisionDecimal("2", precision);
}
return result;
}
HighPrecisionDecimal eulerNumber(size_t precision) {
HighPrecisionDecimal result("0", precision);
HighPrecisionDecimal factorial("1", precision);
for (size_t i = 0; i < precision * 2; ++i) {
result += HighPrecisionDecimal("1", precision) / factorial;
if (i > 0) {
factorial *= HighPrecisionDecimal(to_string(i), precision);
}
}
return result;
}
HighPrecisionDecimal goldenRatio(size_t precision) {
HighPrecisionDecimal five("5", precision);
HighPrecisionDecimal sqrtFive = five.sqrt();
HighPrecisionDecimal two("2", precision);
return (HighPrecisionDecimal("1", precision) + sqrtFive) / two;
}
void demonstrateHighPrecisionInt() {
cout << "=== High Precision Integer Demonstration ===" << endl;
HighPrecisionInt a("123456789012345678901234567890");
HighPrecisionInt b("987654321098765432109876543210");
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "a + b = " << a + b << endl;
cout << "a - b = " << a - b << endl;
cout << "a * b = " << a * b << endl;
cout << "a / b = " << a / b << endl;
cout << "a % b = " << a % b << endl;
HighPrecisionInt c("2");
HighPrecisionInt d("100");
cout << "2^100 = " << c.pow(d) << endl;
HighPrecisionInt e("100");
cout << "100! = " << e.factorial() << endl;
HighPrecisionInt f("12345");
HighPrecisionInt g("7890");
cout << "gcd(12345, 7890) = " << f.gcd(g) << endl;
cout << "lcm(12345, 7890) = " << f.lcm(g) << endl;
cout << endl;
}
void demonstrateHighPrecisionDecimal() {
cout << "=== High Precision Decimal Demonstration ===" << endl;
HighPrecisionDecimal a("1234567890.12345678901234567890", 50);
HighPrecisionDecimal b("9876543210.98765432109876543210", 50);
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "a + b = " << a + b << endl;
cout << "a - b = " << a - b << endl;
cout << "a * b = " << a * b << endl;
cout << "a / b = " << a / b << endl;
HighPrecisionDecimal c("2.0", 50);
HighPrecisionInt d("10");
cout << "2.0^10 = " << c.pow(d) << endl;
HighPrecisionDecimal e("2.0", 50);
cout << "sqrt(2.0) = " << e.sqrt() << endl;
cout << "pi (50 digits) = " << pi(50) << endl;
cout << "e (50 digits) = " << eulerNumber(50) << endl;
cout << "Golden ratio (50 digits) = " << goldenRatio(50) << endl;
cout << "pi in scientific notation: " << pi(50).toScientificNotation() << endl;
cout << endl;
}
int main() {
demonstrateHighPrecisionInt();
demonstrateHighPrecisionDecimal();
cout << "=== Advanced Calculations ===" << endl;
HighPrecisionInt largeFactorialInput("200");
cout << "Sum of factorials from 0! to 200! = " << factorialSeriesSum(largeFactorialInput) << endl;
HighPrecisionDecimal preciseCalculation("0.1234567890123456789012345678901234567890", 100);
preciseCalculation = preciseCalculation.pow(HighPrecisionInt(5));
cout << "0.123456789...^5 (100 digits) = " << preciseCalculation << endl;
return 0;
}