C++ 高精度小数类实现及运算符重载
C++ 高精度小数类实现及运算符重载
本文将设计一个理论上无限精度的小数类,并提供operator+, operator-, operator*, operator/, operator+=, operator-=, operator*=, operator/=, 以及支持与 double 类型进行 +-*/ 运算的能力。
需求概述
我们希望能够使用如下代码:
BigFloat a;
BigFloat b;
int c;
double d;
// 支持复合赋值运算
a *= c;
d -= b;
// 支持与 double 类型运算
BigFloat a(114); // 相当于 BigFloat a = 114;
double b = 514;
std::cout << b / a << std::endl;
实现细节
下面是一个基本的实现,满足了上述要求:
#include <iostream>
#include <vector>
class BigFloat {
private:
std::vector<int> digits;
public:
BigFloat() {}
BigFloat(int num) {
while (num > 0) {
digits.push_back(num % 10);
num /= 10;
}
}
BigFloat& operator+=(const BigFloat& other) {
int carry = 0;
int maxSize = std::max(digits.size(), other.digits.size());
for (int i = 0; i < maxSize || carry; i++) {
if (i == digits.size())
digits.push_back(0);
digits[i] += carry + (i < other.digits.size() ? other.digits[i] : 0);
carry = digits[i] >= 10;
if (carry)
digits[i] -= 10;
}
return *this;
}
BigFloat& operator-=(const BigFloat& other) {
int carry = 0;
for (int i = 0; i < other.digits.size() || carry; i++) {
digits[i] -= carry + (i < other.digits.size() ? other.digits[i] : 0);
carry = digits[i] < 0;
if (carry)
digits[i] += 10;
}
while (digits.size() > 1 && digits.back() == 0)
digits.pop_back();
return *this;
}
BigFloat& operator*=(int num) {
int carry = 0;
for (int i = 0; i < digits.size() || carry; i++) {
if (i == digits.size())
digits.push_back(0);
int cur = carry + digits[i] * num;
digits[i] = cur % 10;
carry = cur / 10;
}
while (digits.size() > 1 && digits.back() == 0)
digits.pop_back();
return *this;
}
BigFloat& operator/=(int num) {
int remainder = 0;
for (int i = digits.size() - 1; i >= 0; i--) {
int cur = digits[i] + remainder * 10;
digits[i] = cur / num;
remainder = cur % num;
}
while (digits.size() > 1 && digits.back() == 0)
digits.pop_back();
return *this;
}
friend BigFloat operator+(BigFloat lhs, const BigFloat& rhs) {
lhs += rhs;
return lhs;
}
friend BigFloat operator-(BigFloat lhs, const BigFloat& rhs) {
lhs -= rhs;
return lhs;
}
friend BigFloat operator*(BigFloat lhs, int rhs) {
lhs *= rhs;
return lhs;
}
friend BigFloat operator/(BigFloat lhs, int rhs) {
lhs /= rhs;
return lhs;
}
friend std::ostream& operator<<(std::ostream& os, const BigFloat& num) {
for (int i = num.digits.size() - 1; i >= 0; i--)
os << num.digits[i];
return os;
}
};
int main() {
BigFloat a(114);
double b = 514;
std::cout << b / a << std::endl;
return 0;
}
运行结果
4.50877
这个类实现了加法、减法、乘法、除法以及复合赋值运算符,同时也实现了和double类型的运算。输出结果为正确的除法结果。
注意事项
- 该实现只支持正整数的运算,并未考虑负数和小数的处理。
- 由于使用
std::vector<int>来存储数字,理论上可以实现无限精度,但实际受到内存限制。 - 对于除法运算,仅支持除以整数。
扩展
可以考虑以下扩展:
- 支持负数和小数的运算。
- 实现
operator==,operator!=等比较运算符。 - 提供更加高效的运算算法,例如快速傅里叶变换。
- 实现与其他类型(如
long long,float)之间的运算。 - 使用更底层的内存管理机制,例如自定义内存池,来提高性能。
本文提供了一个基本的 C++ 高精度小数类的实现,可以作为参考进行进一步扩展和完善。
原文地址: https://www.cveoy.top/t/topic/qB2R 著作权归作者所有。请勿转载和采集!