#include #include #include #include namespace bstl { BigDecimal::BigDecimal() : unscaledValue_(0), scale_(0) {} BigDecimal::BigDecimal(int value) : unscaledValue_(value), scale_(0) {} BigDecimal::BigDecimal(long long value) : unscaledValue_(value), scale_(0) {} BigDecimal::BigDecimal(double value) : scale_(0) { if (value == 0.0) { unscaledValue_ = 0; scale_ = 0; return; } // 将浮点数转换为字符串,然后解析 std::ostringstream oss; oss.precision(15); oss << value; *this = BigDecimal(oss.str()); } BigDecimal::BigDecimal(const std::string& value) : unscaledValue_(0), scale_(0) { if (value.empty()) { return; } std::string text = value; // 去掉前后空格 size_t start = 0, end = text.size(); while (start < end && text[start] == ' ') start++; while (end > start && text[end - 1] == ' ') end--; text = text.substr(start, end - start); if (text.empty()) { return; } // 查找小数点位置 size_t dotPos = text.find('.'); if (dotPos != std::string::npos) { scale_ = text.size() - dotPos - 1; std::string digits = text.substr(0, dotPos) + text.substr(dotPos + 1); unscaledValue_ = BigInteger(digits); } else { scale_ = 0; unscaledValue_ = BigInteger(text); } } BigDecimal::BigDecimal(const char* value) : BigDecimal(value == nullptr ? std::string("0") : std::string(value)) {} BigDecimal::BigDecimal(const BigInteger& unscaledValue, int scale) : unscaledValue_(unscaledValue), scale_(scale) { if (scale < 0) { throw std::invalid_argument("scale cannot be negative"); } } bool BigDecimal::isZero() const { return unscaledValue_.isZero(); } int BigDecimal::sign() const { return unscaledValue_.sign(); } int BigDecimal::getScale() const { return scale_; } BigInteger BigDecimal::getUnscaledValue() const { return unscaledValue_; } std::string BigDecimal::toString() const { if (isZero()) { return "0"; } std::string digitStr = unscaledValue_.toString(); // 处理符号 bool negative = false; if (digitStr[0] == '-') { negative = true; digitStr = digitStr.substr(1); } // 插入小数点 if (scale_ == 0) { return (negative ? "-" : "") + digitStr; } if (static_cast(digitStr.size()) <= scale_) { // 需要前置 "0." std::string result = "0."; for (int i = 0; i < scale_ - static_cast(digitStr.size()); i++) { result += "0"; } result += digitStr; return (negative ? "-" : "") + result; } int dotPos = digitStr.size() - scale_; std::string result = digitStr.substr(0, dotPos) + "." + digitStr.substr(dotPos); return (negative ? "-" : "") + result; } void BigDecimal::alignScale(BigInteger& lhs, int& lhsScale, BigInteger& rhs, int& rhsScale) { if (lhsScale < rhsScale) { // 左边需要扩大 for (int i = 0; i < rhsScale - lhsScale; i++) { lhs = lhs * BigInteger(10); } lhsScale = rhsScale; } else if (lhsScale > rhsScale) { // 右边需要扩大 for (int i = 0; i < lhsScale - rhsScale; i++) { rhs = rhs * BigInteger(10); } rhsScale = lhsScale; } } bool BigDecimal::operator==(const BigDecimal& other) const { if (isZero() && other.isZero()) return true; BigInteger lhs = unscaledValue_; BigInteger rhs = other.unscaledValue_; int lhsScale = scale_; int rhsScale = other.scale_; alignScale(lhs, lhsScale, rhs, rhsScale); return lhs == rhs; } bool BigDecimal::operator!=(const BigDecimal& other) const { return !(*this == other); } bool BigDecimal::operator<(const BigDecimal& other) const { if (unscaledValue_.sign() != other.unscaledValue_.sign()) { return unscaledValue_.sign() < other.unscaledValue_.sign(); } BigInteger lhs = unscaledValue_; BigInteger rhs = other.unscaledValue_; int lhsScale = scale_; int rhsScale = other.scale_; alignScale(lhs, lhsScale, rhs, rhsScale); if (unscaledValue_.sign() >= 0) { return lhs < rhs; } else { return lhs > rhs; } } bool BigDecimal::operator>(const BigDecimal& other) const { return other < *this; } bool BigDecimal::operator<=(const BigDecimal& other) const { return *this < other || *this == other; } bool BigDecimal::operator>=(const BigDecimal& other) const { return other <= *this; } bool BigDecimal::operator==(int value) const { return *this == BigDecimal(value); } bool BigDecimal::operator!=(int value) const { return !(*this == value); } bool BigDecimal::operator<(int value) const { return *this < BigDecimal(value); } bool BigDecimal::operator>(int value) const { return *this > BigDecimal(value); } bool BigDecimal::operator<=(int value) const { return *this <= BigDecimal(value); } bool BigDecimal::operator>=(int value) const { return *this >= BigDecimal(value); } bool BigDecimal::operator==(double value) const { return *this == BigDecimal(value); } bool BigDecimal::operator!=(double value) const { return !(*this == value); } bool BigDecimal::operator<(double value) const { return *this < BigDecimal(value); } bool BigDecimal::operator>(double value) const { return *this > BigDecimal(value); } bool BigDecimal::operator<=(double value) const { return *this <= BigDecimal(value); } bool BigDecimal::operator>=(double value) const { return *this >= BigDecimal(value); } BigDecimal BigDecimal::operator+() const { return *this; } BigDecimal BigDecimal::operator-() const { if (isZero()) { return BigDecimal(0); } return BigDecimal(-unscaledValue_, scale_); } BigDecimal& BigDecimal::operator+=(const BigDecimal& other) { *this = *this + other; return *this; } BigDecimal& BigDecimal::operator-=(const BigDecimal& other) { *this = *this - other; return *this; } BigDecimal& BigDecimal::operator*=(const BigDecimal& other) { *this = *this * other; return *this; } BigDecimal& BigDecimal::operator/=(const BigDecimal& other) { *this = *this / other; return *this; } BigDecimal BigDecimal::operator+(const BigDecimal& other) const { if (isZero()) return other; if (other.isZero()) return *this; BigInteger lhs = unscaledValue_; BigInteger rhs = other.unscaledValue_; int lhsScale = scale_; int rhsScale = other.scale_; alignScale(lhs, lhsScale, rhs, rhsScale); return BigDecimal(lhs + rhs, lhsScale); } BigDecimal BigDecimal::operator-(const BigDecimal& other) const { return *this + (-other); } BigDecimal BigDecimal::operator*(const BigDecimal& other) const { if (isZero() || other.isZero()) { return BigDecimal(0); } BigInteger result = unscaledValue_ * other.unscaledValue_; int resultScale = scale_ + other.scale_; return BigDecimal(result, resultScale); } BigDecimal BigDecimal::operator/(const BigDecimal& other) const { if (other.isZero()) { throw std::invalid_argument("division by zero"); } if (isZero()) { return BigDecimal(0); } // 先对齐 scale,然后做整数除法 BigInteger lhs = unscaledValue_; BigInteger rhs = other.unscaledValue_; int lhsScale = scale_; int rhsScale = other.scale_; // 使用更高的精度进行除法 // 乘以 10^precision 来获得更多的精度 int precision = 10; for (int i = 0; i < precision; i++) { lhs = lhs * BigInteger(10); } BigInteger quotient = lhs / rhs; int resultScale = lhsScale - rhsScale + precision; return BigDecimal(quotient, resultScale); } BigDecimal BigDecimal::abs() const { if (unscaledValue_.sign() >= 0) { return *this; } return BigDecimal(-unscaledValue_, scale_); } BigDecimal BigDecimal::round(int scale) const { if (scale < 0) { throw std::invalid_argument("scale cannot be negative"); } if (scale >= scale_) { return *this; } // 简单实现:直接截断到指定小数位数 int diff = scale_ - scale; BigInteger divisor = BigInteger(10); for (int i = 1; i < diff; i++) { divisor = divisor * BigInteger(10); } BigInteger rounded = unscaledValue_ / divisor; return BigDecimal(rounded, scale); } } // namespace bstl