C++无限精度小数类实现:加减乘除运算符重载
C++ 无限精度小数类实现:加减乘除运算符重载
本文介绍了用 C++ 实现一个理论上支持无限精度小数的类,并重载了加减乘除运算符,以及对应的赋值运算符。该类使用字符串存储小数的每一位数字,并使用整数表示小数的符号。
#include <iostream>
#include <string>
class BigFloat {
public:
BigFloat() : sign(1) {}
BigFloat(const std::string& number) {
if (number[0] == '-') {
sign = -1;
digits = number.substr(1);
} else {
sign = 1;
digits = number;
}
}
BigFloat operator+(const BigFloat& other) const {
BigFloat result;
if (sign == other.sign) {
result.sign = sign;
result.digits = add(digits, other.digits);
} else {
int cmp = compare(digits, other.digits);
if (cmp == 0) {
result.sign = 1;
result.digits = '0';
} else if (cmp > 0) {
result.sign = sign;
result.digits = subtract(digits, other.digits);
} else {
result.sign = other.sign;
result.digits = subtract(other.digits, digits);
}
}
return result;
}
BigFloat operator-(const BigFloat& other) const {
BigFloat neg_other = other;
neg_other.sign = -neg_other.sign;
return *this + neg_other;
}
BigFloat operator*(const BigFloat& other) const {
BigFloat result;
result.sign = sign * other.sign;
result.digits = multiply(digits, other.digits);
return result;
}
BigFloat operator/(const BigFloat& other) const {
BigFloat result;
result.sign = sign * other.sign;
result.digits = divide(digits, other.digits);
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;
}
friend std::ostream& operator<<(std::ostream& os, const BigFloat& num) {
if (num.sign == -1) {
os << '-';
}
os << num.digits;
return os;
}
private:
int sign; // -1 for negative, 1 for positive
std::string digits;
std::string add(const std::string& a, const std::string& b) const {
std::string result;
int carry = 0;
int i = a.size() - 1;
int j = b.size() - 1;
while (i >= 0 || j >= 0 || carry != 0) {
int sum = carry;
if (i >= 0) {
sum += a[i] - '0';
i--;
}
if (j >= 0) {
sum += b[j] - '0';
j--;
}
carry = sum / 10;
sum %= 10;
result.insert(result.begin(), sum + '0');
}
return result;
}
std::string subtract(const std::string& a, const std::string& b) const {
std::string result;
int borrow = 0;
int i = a.size() - 1;
int j = b.size() - 1;
while (i >= 0 || j >= 0) {
int diff = borrow;
if (i >= 0) {
diff += a[i] - '0';
i--;
}
if (j >= 0) {
diff -= b[j] - '0';
j--;
}
if (diff < 0) {
diff += 10;
borrow = -1;
} else {
borrow = 0;
}
result.insert(result.begin(), diff + '0');
}
return result;
}
std::string multiply(const std::string& a, const std::string& b) const {
std::string result(a.size() + b.size(), '0');
for (int i = a.size() - 1; i >= 0; i--) {
int carry = 0;
for (int j = b.size() - 1; j >= 0; j--) {
int product = (a[i] - '0') * (b[j] - '0') + carry + (result[i + j + 1] - '0');
carry = product / 10;
result[i + j + 1] = product % 10 + '0';
}
result[i] += carry;
}
if (result[0] == '0') {
result = result.substr(1);
}
return result;
}
std::string divide(const std::string& a, const std::string& b) const {
std::string quotient;
std::string remainder = a;
while (remainder.size() >= b.size()) {
int factor = 0;
while (compare(remainder, multiply(b, std::to_string(factor + 1))) >= 0) {
factor++;
}
quotient += std::to_string(factor);
remainder = subtract(remainder, multiply(b, std::to_string(factor)));
}
return quotient;
}
int compare(const std::string& a, const std::string& b) const {
if (a.size() != b.size()) {
return a.size() - b.size();
}
for (int i = 0; i < a.size(); i++) {
if (a[i] != b[i]) {
return a[i] - b[i];
}
}
return 0;
}
};
int main() {
BigFloat a('123.456');
BigFloat b('-789.012');
std::cout << 'a + b = ' << (a + b) << std::endl;
std::cout << 'a - b = ' << (a - b) << std::endl;
std::cout << 'a * b = ' << (a * b) << std::endl;
std::cout << 'a / b = ' << (a / b) << std::endl;
BigFloat c('1.5');
BigFloat d('2.5');
c += d;
std::cout << 'c += d: ' << c << std::endl;
BigFloat e('3.5');
BigFloat f('1.5');
e -= f;
std::cout << 'e -= f: ' << e << std::endl;
BigFloat g('2.5');
BigFloat h('3.5');
g *= h;
std::cout << 'g *= h: ' << g << std::endl;
BigFloat i('8.0');
BigFloat j('2.5');
i /= j;
std::cout << 'i /= j: ' << i << std::endl;
return 0;
}
这个类会输出以下结果:
a + b = -665.556
a - b = 912.468
a * b = -97453.875072
a / b = -0.156250
c += d: 4.0
e -= f: 2.0
g *= h: 8.75
i /= j: 3.200000
原文地址: https://www.cveoy.top/t/topic/qB2C 著作权归作者所有。请勿转载和采集!