C++高精度实现

#include <bits/stdc++.h>
using namespace std;
struct fantastic {
    int len, s[9999];

    fantastic() {
        memset(s, 0, sizeof(s));
        len = 1;
    }
    fantastic& operator=(const char* num) {
        len = strlen(num);
        for (int i = 0; i < len; ++i)
            s[i] = num[len - i - 1] - '0';
        return *this;
    }

    fantastic& operator=(const int num) {
        char a[9999];
        sprintf(a, "%d", num);
        *this = a;
        return *this;
    }

    fantastic(const int num) { *this = num; }
    fantastic(const char* num) { *this = num; }
    bool operator<(const fantastic& a) const {
        if (len != a.len) return len < a.len;
        for (int i = len - 1; i >= 0; --i)
            if (s[i] != a.s[i]) return s[i] < a.s[i];
        return false;
    }

    bool operator>=(const fantastic& a) const { return !(*this < a); }
    bool operator==(const fantastic& a) const {
        if (len != a.len) return false;
        for (int i = 0; i < len; ++i)
            if (s[i] != a.s[i]) return false;
        return true;
    }
    bool operator!=(const fantastic& a) const { return !(*this == a); }

    fantastic operator+(const fantastic& a) {
        fantastic c;
        c.len = max(len, a.len) + 1;
        for (int i = 0, x = 0; i < c.len; ++i) {
            c.s[i] = s[i] + a.s[i] + x;
            x = c.s[i] / 10;
            c.s[i] %= 10;
        }
        if (c.s[c.len - 1] == 0) --c.len;
        return c;
    }

    fantastic operator-(const fantastic& a) const{
        if (*this < a) throw invalid_argument("Negative result");
        fantastic c;
        c.len = len;
        int borrow = 0;
        for (int i = 0; i < c.len; ++i) {
            int sub = s[i] - borrow;
            if (i < a.len) sub -= a.s[i];
            if (sub < 0) { sub += 10; borrow = 1; } 
            else borrow = 0;
            c.s[i] = sub;
        }
        while (c.len > 1 && c.s[c.len-1] == 0) --c.len;
        return c;
    }

    fantastic operator*(const fantastic& x) const{
        fantastic c;
        c.len = len + x.len;
        for (int i = 0; i < len; ++i)
            for (int j = 0; j < x.len; ++j) {
                c.s[i+j] += s[i] * x.s[j];
                c.s[i+j+1] += c.s[i+j] / 10;
                c.s[i+j] %= 10;
            }
        while (c.len > 1 && c.s[c.len-1] == 0) --c.len;
        return c;
    }

    fantastic operator/(const fantastic& divisor) const {
    if (divisor == fantastic(0)) throw invalid_argument("Division by zero");
    fantastic quotient, remainder = *this;
    quotient.len = max(1, len - divisor.len + 1);
    
    for (int i = quotient.len-1; i >= 0; --i) {
        fantastic temp = divisor;
        temp.shift_left(i);
        
        int count = 0;
        while (remainder >= temp) {
            remainder = remainder - temp;
            count++;
        }
        quotient.s[i] = count;
    }
    while (quotient.len > 1 && quotient.s[quotient.len-1] == 0)
        --quotient.len;
    return quotient;
}

    fantastic operator%(const fantastic& divisor) const {
    if (divisor == fantastic(0)) throw invalid_argument("Modulus by zero");
    fantastic quotient = *this / divisor;
    fantastic product = quotient * divisor;
    return *this - product;
}
    void shift_left(int n) {
        if (len == 1 && s[0] == 0) return;
        for (int i = len-1; i >= 0; --i) s[i+n] = s[i];
        for (int i = 0; i < n; ++i) s[i] = 0;
        len += n;
    }
};
ostream& operator<<(ostream& out, const fantastic& x) {
    for (int i = x.len-1; i >= 0; --i) out << x.s[i];
    return out;
}

istream& operator>>(istream& in, fantastic& x) {
    char num[9999];
    in >> num;
    x = num;
    return in;
}

解析

#include <bits/stdc++.h> // 包含大部分标准库,但可能影响编译速度和可移植性
using namespace std;     // 可能引发命名冲突,但简化代码

struct fantastic {
    int len, s[9999];    // len为数字位数,s逆序存储各位数字(如"123"存为s[0]=3,s[1]=2,s[2]=1)

    fantastic() {         // 默认构造函数,初始化数字为0
        memset(s, 0, sizeof(s));
        len = 1;
    }

    // 从字符串赋值,逆序存储
    fantastic& operator=(const char* num) {
        len = strlen(num);
        for (int i = 0; i < len; ++i)
            s[i] = num[len - i - 1] - '0'; // 反转字符顺序存入数组
        return *this;
    }

    // 从整数赋值,转换为字符串后处理
    fantastic& operator=(const int num) {
        char a[9999];
        sprintf(a, "%d", num);
        *this = a;  // 复用字符串赋值逻辑
        return *this;
    }

    fantastic(const int num) { *this = num; }    // 整数构造函数
    fantastic(const char* num) { *this = num; }  // 字符串构造函数

    // 比较运算符:按位数和逐位值比较
    bool operator<(const fantastic& a) const {
        if (len != a.len) return len < a.len;
        for (int i = len-1; i >= 0; --i)  // 从高位开始比较
            if (s[i] != a.s[i]) return s[i] < a.s[i];
        return false;
    }

    bool operator>=(const fantastic& a) const { return !(*this < a); }
    
    // 相等判断需位数和各位值完全相同
    bool operator==(const fantastic& a) const {
        if (len != a.len) return false;
        for (int i = 0; i < len; ++i)
            if (s[i] != a.s[i]) return false;
        return true;
    }
    
    bool operator!=(const fantastic& a) const { return !(*this == a); }

    // 加法:逐位相加处理进位
    fantastic operator+(const fantastic& a) {
        fantastic c;
        c.len = max(len, a.len) + 1; // 结果位数可能比最大位数多1
        for (int i = 0, x = 0; i < c.len; ++i) {
            c.s[i] = s[i] + a.s[i] + x;
            x = c.s[i] / 10;  // 计算进位
            c.s[i] %= 10;
        }
        if (c.s[c.len-1] == 0) --c.len; // 去除前导零
        return c;
    }

    // 减法:确保被减数不小于减数,处理借位
    fantastic operator-(const fantastic& a) const {
        if (*this < a) throw invalid_argument("Negative result");
        fantastic c;
        c.len = len;
        int borrow = 0;
        for (int i = 0; i < c.len; ++i) {
            int sub = s[i] - borrow;
            if (i < a.len) sub -= a.s[i];
            borrow = sub < 0 ? 1 : 0;  // 计算借位
            c.s[i] = (sub + 10) % 10;  // 处理负数结果
        }
        while (c.len > 1 && c.s[c.len-1] == 0) --c.len; // 去除前导零
        return c;
    }

    // 乘法:竖式乘法,处理进位
    fantastic operator*(const fantastic& x) const {
        fantastic c;
        c.len = len + x.len; // 最大可能位数
        for (int i = 0; i < len; ++i)
            for (int j = 0; j < x.len; ++j) {
                c.s[i+j] += s[i] * x.s[j];      // 累加乘积
                c.s[i+j+1] += c.s[i+j] / 10;    // 处理进位
                c.s[i+j] %= 10;
            }
        while (c.len > 1 && c.s[c.len-1] == 0) --c.len; // 去除前导零
        return c;
    }

    // 除法:长除法,通过减法试商
    fantastic operator/(const fantastic& divisor) const {
        if (divisor == fantastic(0)) throw invalid_argument("Division by zero");
        fantastic quotient, remainder = *this;
        quotient.len = max(1, len - divisor.len + 1); // 商位数估计
        for (int i = quotient.len-1; i >= 0; --i) {
            fantastic temp = divisor;
            temp.shift_left(i); // 除数左移i位(相当于乘10^i)
            int count = 0;
            while (remainder >= temp) { // 试减统计当前位商值
                remainder = remainder - temp;
                count++;
            }
            quotient.s[i] = count;
        }
        while (quotient.len > 1 && quotient.s[quotient.len-1] == 0)
            --quotient.len; // 去除前导零
        return quotient;
    }

    // 取模:利用除法结果计算余数
    fantastic operator%(const fantastic& divisor) const {
        fantastic quotient = *this / divisor;
        return *this - quotient * divisor; // 余数=被除数-商×除数
    }

    // 左移n位(数值乘10^n),用于除法运算
    void shift_left(int n) {
        if (len == 1 && s[0] == 0) return; // 0左移不变
        for (int i = len-1; i >= 0; --i) 
            s[i+n] = s[i];  // 高位右移n位
        for (int i = 0; i < n; ++i)
            s[i] = 0;       // 低位补零
        len += n;           // 更新长度
    }
};

// 输出运算符:逆序打印数组
ostream& operator<<(ostream& out, const fantastic& x) {
    for (int i = x.len-1; i >= 0; --i) out << x.s[i];
    return out;
}

// 输入运算符:读取字符串构造对象
istream& operator>>(istream& in, fantastic& x) {
    char num[9999];
    in >> num;
    x = num;  // 调用字符串赋值运算符
    return in;
}

/* 潜在问题提示:
1. 数组固定大小9999可能溢出,超长输入导致越界。
2. 乘法和移位可能超出数组范围,需确保操作数位数足够小。
3. 除法效率较低,大数运算时性能不佳。
4. 未处理负数,仅限于非负整数运算。
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值