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++ 高精度小数类的实现,可以作为参考进行进一步扩展和完善。

C++ 高精度小数类实现及运算符重载

原文地址: https://www.cveoy.top/t/topic/qB2R 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录