下午很无聊的打了一个这个,,,,
起因是写dp题的时候正好要用到高精 而我是一个非常讨厌写高精度的人 于是一气之下码了
嗯这个是我的class
class BigInteger {
private:
vector < int > digits;
bool isNegative;
void removeLeadingZeros() {
while (digits.size() > 1 && digits.back() == 0) digits.pop_back();
if (digits.empty()) {
digits.push_back(0);
isNegative = false;
} else if (digits.size() == 1 && digits[0] == 0) isNegative = false;
}
int compareAbs(const BigInteger& other) const {
if (digits.size() != other.digits.size()) return digits.size() > other.digits.size() ? 1 : -1;
for (int i = digits.size() - 1; i >= 0; --i)
if (digits[i] != other.digits[i]) return digits[i] > other.digits[i] ? 1 : -1;
return 0;
}
public:
BigInteger() : isNegative(false) { digits.push_back(0); }
BigInteger(const string& s) {
isNegative = false;
int start = 0;
if (!s.empty() && s[0] == '-') {isNegative = true; start = 1;}
digits.clear();
for (int i = s.size() - 1; i >= start; --i) {
if (!isdigit(s[i])) throw invalid_argument("Invalid number string");
digits.push_back(s[i] - '0');
}
removeLeadingZeros();
}
BigInteger(long long num) {
isNegative = num < 0;
num = std::abs(num);
digits.clear();
if (num == 0) digits.push_back(0);
else while (num > 0) {digits.push_back(num % 10); num /= 10;}
removeLeadingZeros();
}
BigInteger abs() const {
BigInteger result = *this;
result.isNegative = false;
return result;
}
friend bool operator<(const BigInteger& a, const BigInteger& b) {
if (a.isNegative != b.isNegative) return a.isNegative;
return a.isNegative ? a.compareAbs(b) > 0 : a.compareAbs(b) < 0;
}
friend bool operator>(const BigInteger& a, const BigInteger& b) { return b < a; }
friend bool operator<=(const BigInteger& a, const BigInteger& b) { return !(a > b); }
friend bool operator>=(const BigInteger& a, const BigInteger& b) { return !(a < b); }
friend bool operator==(const BigInteger& a, const BigInteger& b) { return a.isNegative == b.isNegative && a.digits == b.digits;}
friend bool operator!=(const BigInteger& a, const BigInteger& b) { return !(a == b); }
BigInteger operator-() const {
BigInteger result = *this;
if (result != BigInteger(0)) result.isNegative = !result.isNegative;
return result;
}
friend BigInteger operator+(const BigInteger& a, const BigInteger& b) {
if (a.isNegative == b.isNegative) {
BigInteger result;
result.digits.resize(max(a.digits.size(), b.digits.size()) + 1, 0);
int carry = 0;
for (int i = 0; i < result.digits.size(); ++i) {
int sum = carry;
if (i < a.digits.size()) sum += a.digits[i];
if (i < b.digits.size()) sum += b.digits[i];
result.digits[i] = sum % 10;
carry = sum / 10;
}
result.isNegative = a.isNegative;
result.removeLeadingZeros();
return result;
} else {
if (a.compareAbs(b) >= 0) {
BigInteger result;
result.digits.resize(a.digits.size(), 0);
int borrow = 0;
for (int i = 0; i < a.digits.size(); ++i) {
int sub = a.digits[i] - borrow;
if (i < b.digits.size()) sub -= b.digits[i];
if (sub < 0) sub += 10, borrow = 1;
else borrow = 0;
result.digits[i] = sub;
}
result.isNegative = a.isNegative;
result.removeLeadingZeros();
return result;
} else return b + a;
}
}
friend BigInteger operator-(const BigInteger& a, const BigInteger& b) {return a + (-b);}
friend BigInteger operator*(const BigInteger& a, const BigInteger& b) {
BigInteger result;
result.digits.resize(a.digits.size() + b.digits.size(), 0);
for (int i = 0; i < a.digits.size(); ++i) {
int carry = 0;
for (int j = 0; j < b.digits.size(); ++j) {
int temp = result.digits[i + j] + a.digits[i] * b.digits[j] + carry;
result.digits[i + j] = temp % 10;
carry = temp / 10;
}
if (carry > 0) result.digits[i + b.digits.size()] += carry;
}
result.isNegative = a.isNegative != b.isNegative;
result.removeLeadingZeros();
return result;
}
friend BigInteger operator/(const BigInteger& a, const BigInteger& b) {
if (b == BigInteger(0)) throw runtime_error("Division by zero");
BigInteger dividend = a.abs();
BigInteger divisor = b.abs();
if (dividend < divisor) return BigInteger(0);
vector rev_dividend(dividend.digits.rbegin(), dividend.digits.rend());
BigInteger current_remainder;
vector quotient_digits;
for (int digit : rev_dividend) {
current_remainder = current_remainder * BigInteger(10) + BigInteger(digit);
int d = 9;
BigInteger product;
for (; d >= 0; --d) {
product = divisor * d;
if (product <= current_remainder) break;
}
quotient_digits.push_back(d);
current_remainder = current_remainder - product;
}
reverse(quotient_digits.begin(), quotient_digits.end());
BigInteger quotient;
quotient.digits = quotient_digits;
quotient.isNegative = a.isNegative != b.isNegative;
quotient.removeLeadingZeros();
return quotient;
}
friend BigInteger operator%(const BigInteger& a, const BigInteger& b) {
BigInteger quotient = a / b;
return a - quotient * b;
}
friend ostream& operator<<(ostream& os, const BigInteger& num) {
if (num.isNegative && num != BigInteger(0)) os << '-';
for (auto it = num.digits.rbegin(); it != num.digits.rend(); ++it) os << *it;
return os;
}
BigInteger pow(int exponent) const {
if (exponent < 0) throw invalid_argument("BigInteger pow: Negative exponent not supported");
if (exponent == 0) {
if (*this == BigInteger(0)) throw invalid_argument("BigInteger pow: 0^0 undefined");
return BigInteger(1);
}
BigInteger result(1);
BigInteger base = *this;
int exp = exponent;
while (exp > 0) {
if (exp % 2 == 1) result = result * base;
base = base * base;
exp /= 2;
}
return result;
}
};
用法是这样的
//加减乘除 写了重载运算符 直接用就可以
string s1, s2; cin >> s1 >> s2;
BigInteger a(s1), b(s2);
cout << a + b << "\n" << a - b << "\n" << a * b << "\n" << a / b << "\n";
快速幂 复杂度是O(log)的 用法这样
//表示a的b次方
string s; cin >> s;
BigInteger a(s); int b;
cout << a.pow(b) << "\n";
我真厉害((((( 造福后人