C++请设计一个理论无限精度小数的类并提供operator+operator-operatoroperatoroperator+=operator-=operator=operator=并支持一个double +- 这个类的对象就像:BigFloat a;BigFloat b;int c;double d;诸如a = cd -= b的行为是受支持的
下面是一个简单的实现,可以实现无限精度小数的类:
#include <iostream>
#include <vector>
class BigFloat {
private:
std::vector<int> digits;
int decimalPoint;
bool negative;
public:
BigFloat() : decimalPoint(0), negative(false) {}
BigFloat(int num) {
if (num < 0) {
negative = true;
num *= -1;
} else {
negative = false;
}
decimalPoint = 0;
while (num > 0) {
digits.push_back(num % 10);
num /= 10;
}
}
BigFloat(double num) {
if (num < 0) {
negative = true;
num *= -1;
} else {
negative = false;
}
decimalPoint = 0;
while (num > 0) {
digits.insert(digits.begin(), static_cast<int>(num) % 10);
num /= 10;
}
}
BigFloat operator+(const BigFloat& other) const {
BigFloat result;
result.digits = digits;
result.decimalPoint = decimalPoint;
int diff = decimalPoint - other.decimalPoint;
if (diff > 0) {
for (int i = 0; i < diff; ++i) {
result.digits.insert(result.digits.begin(), 0);
}
} else if (diff < 0) {
for (int i = 0; i < -diff; ++i) {
result.digits.push_back(0);
}
}
int carry = 0;
for (int i = other.digits.size() - 1; i >= 0; --i) {
int sum = result.digits[i] + other.digits[i] + carry;
result.digits[i] = sum % 10;
carry = sum / 10;
}
if (carry > 0) {
result.digits.insert(result.digits.begin(), carry);
++result.decimalPoint;
}
return result;
}
BigFloat operator-(const BigFloat& other) const {
BigFloat result;
result.digits = digits;
result.decimalPoint = decimalPoint;
int diff = decimalPoint - other.decimalPoint;
if (diff > 0) {
for (int i = 0; i < diff; ++i) {
result.digits.insert(result.digits.begin(), 0);
}
} else if (diff < 0) {
for (int i = 0; i < -diff; ++i) {
result.digits.push_back(0);
}
}
int borrow = 0;
for (int i = other.digits.size() - 1; i >= 0; --i) {
int diff = result.digits[i] - other.digits[i] - borrow;
if (diff < 0) {
diff += 10;
borrow = 1;
} else {
borrow = 0;
}
result.digits[i] = diff;
}
return result;
}
BigFloat operator*(const BigFloat& other) const {
BigFloat result;
result.decimalPoint = decimalPoint + other.decimalPoint;
result.digits.resize(digits.size() + other.digits.size(), 0);
for (int i = digits.size() - 1; i >= 0; --i) {
int carry = 0;
for (int j = other.digits.size() - 1; j >= 0; --j) {
int product = digits[i] * other.digits[j] + result.digits[i + j + 1] + carry;
result.digits[i + j + 1] = product % 10;
carry = product / 10;
}
result.digits[i] += carry;
}
while (result.digits.size() > 1 && result.digits.front() == 0) {
result.digits.erase(result.digits.begin());
--result.decimalPoint;
}
return result;
}
BigFloat operator/(const BigFloat& other) const {
BigFloat result;
result.decimalPoint = decimalPoint - other.decimalPoint;
result.digits.resize(digits.size(), 0);
BigFloat remainder = *this;
while (remainder >= other) {
int quotient = 0;
while (remainder >= other * (quotient + 1)) {
++quotient;
}
remainder -= other * quotient;
result += BigFloat(quotient);
result.decimalPoint = decimalPoint - other.decimalPoint;
}
return result;
}
BigFloat& operator+=(const BigFloat& other) {
*this = *this + other;
return *this;
}
BigFloat& operator-=(const BigFloat& other) {
*this = *this - other;
return *this;
}
BigFloat& operator*=(const BigFloat& other) {
*this = *this * other;
return *this;
}
BigFloat& operator/=(const BigFloat& other) {
*this = *this / other;
return *this;
}
bool operator<(const BigFloat& other) const {
if (negative && !other.negative) {
return true;
} else if (!negative && other.negative) {
return false;
} else if (negative && other.negative) {
return (-(*this)) > (-other);
}
if (decimalPoint > other.decimalPoint) {
return false;
} else if (decimalPoint < other.decimalPoint) {
return true;
}
for (int i = 0; i < digits.size(); ++i) {
if (digits[i] < other.digits[i]) {
return true;
} else if (digits[i] > other.digits[i]) {
return false;
}
}
return false;
}
bool operator>(const BigFloat& other) const {
return other < *this;
}
bool operator<=(const BigFloat& other) const {
return !(*this > other);
}
bool operator>=(const BigFloat& other) const {
return !(*this < other);
}
bool operator==(const BigFloat& other) const {
if (decimalPoint != other.decimalPoint || digits.size() != other.digits.size()) {
return false;
}
for (int i = 0; i < digits.size(); ++i) {
if (digits[i] != other.digits[i]) {
return false;
}
}
return true;
}
bool operator!=(const BigFloat& other) const {
return !(*this == other);
}
BigFloat operator-() const {
BigFloat result = *this;
result.negative = !result.negative;
return result;
}
friend std::ostream& operator<<(std::ostream& os, const BigFloat& num);
};
std::ostream& operator<<(std::ostream& os, const BigFloat& num) {
if (num.negative) {
os << "-";
}
for (int i = 0; i < num.digits.size(); ++i) {
if (i == num.decimalPoint) {
os << ".";
}
os << num.digits[i];
}
return os;
}
int main() {
BigFloat a(123456789);
BigFloat b(987654321);
BigFloat c = a + b;
BigFloat d = a - b;
BigFloat e = a * b;
BigFloat f = a / b;
std::cout << "a + b = " << c << std::endl;
std::cout << "a - b = " << d << std::endl;
std::cout << "a * b = " << e << std::endl;
std::cout << "a / b = " << f << std::endl;
double g = 12.345;
BigFloat h = a * g;
std::cout << "a * g = " << h << std::endl;
return 0;
}
这个实现使用一个vector来存储小数的每一位数字,使用一个int来记录小数点的位置,使用一个bool来表示是否为负数。在各个运算符重载函数中,将两个BigFloat对象的小数点对齐,然后根据运算符的不同进行相应的运算
原文地址: https://www.cveoy.top/t/topic/iV1S 著作权归作者所有。请勿转载和采集!