面向对象程序设计(基于C++)0901 ExtremeLong.cpp

该博客详细介绍了如何实现一个名为 ExtremeLong 的大数类,支持大整数的乘法、加法操作,并实现了COPY和MOVE语义。 ExtremeLong类包含构造函数、析构函数、输入输出流操作符、赋值运算符以及大数的比较操作。此外,还特别强调了MOVE语义的正确实现,确保在移动赋值时资源的有效转移。
摘要由CSDN通过智能技术生成

要求

设置以xl,XL的常量,重载* + = += *=,定义COPY和MOVE语义
需要注意MOVE语义下
X a = move(b)等价于 X a{move(b)}

而调用赋值的move,需要
X a; a = move(b)或者 a = func(b) //返回临时变量

头文件

#pragma once
#include<iostream>
#include<bits/stdc++.h>
#include<cstring>

#define M 10000
using namespace std;

class ExtremeLong
{
    int sign;
    int digit;
    int *ptr;
    long long lim;

    int string_err;
    
    void add(ExtremeLong&,const ExtremeLong&, const ExtremeLong&);
public:
    ExtremeLong(int, int);
    ExtremeLong(long, int);
    ExtremeLong(long long, int);
    ExtremeLong(const char*);
    ExtremeLong(const string&);
    ExtremeLong(const ExtremeLong&);
    ~ExtremeLong();
    ExtremeLong(ExtremeLong&&);//move 

    friend istream& operator>>(istream&,ExtremeLong&);
    friend ostream& operator<<(ostream&,const ExtremeLong&);
    ExtremeLong& operator=(const ExtremeLong&);
    ExtremeLong& operator=(ExtremeLong&&);
    ExtremeLong& operator=(long long);
    ExtremeLong& operator*=(const ExtremeLong&);
    ExtremeLong& operator+=(const ExtremeLong&);

    int digits()const;
    int signs()const;
    int operator[](const int)const;
    void resize(long long);
    void carry();
    ExtremeLong abs();
};

ExtremeLong operator*(const ExtremeLong&,const ExtremeLong&);
ExtremeLong operator+(const ExtremeLong&,const ExtremeLong&);
ExtremeLong operator^(const ExtremeLong&,const ExtremeLong&);

ExtremeLong operator""xl(const char*);
ExtremeLong operator""XL(const char*);

bool operator>(const ExtremeLong&,const ExtremeLong&);
bool operator<(const ExtremeLong&,const ExtremeLong&);
bool operator==(const ExtremeLong&,const ExtremeLong&);
bool operator>=(const ExtremeLong&,const ExtremeLong&);
bool operator<=(const ExtremeLong&,const ExtremeLong&);
bool operator!=(const ExtremeLong&,const ExtremeLong&);

implement

#include<iostream>
#include<bits/stdc++.h>
#include<cstring>
#include<climits>
using namespace std;  
#include "ExtremeLong.h"


using namespace std;

void ExtremeLong::add(ExtremeLong& t,const ExtremeLong& ADD ,const ExtremeLong& SUB)
{
    for(int i = 0; i < SUB.digit; i++)
    {
        t.ptr[i] -= SUB.ptr[i];
    }
    for(int i = 0; i < ADD.digit; i++)
    {
        t.ptr[i] += ADD.ptr[i];
    }
}

ExtremeLong::ExtremeLong(int a = 0, int size = 50)
{
    ptr = new int[size];
    memset(ptr,0,size * sizeof(int));
    lim = size;
    sign = 1;

    bool flag = false;
    if(a < 0 && a != INT_MIN)
    {
        a = -a;
        sign = -1;
    }
    else if(a == INT_MIN)
    {
        sign = -1;
        a = INT_MAX;
        flag = true;
    }
    if(flag)
    {
        flag = false;    
        ptr[0]+=1;
    }

    digit = 0;
    while(a)
    {
        ptr[digit++] = a % 10;
        a/=10;
    }
    digit++;

    carry();
}
ExtremeLong::ExtremeLong(long a, int size = 50)
{
    ptr = new int[size];
    memset(ptr,0,size * sizeof(int));
    lim = size;
    sign = 1;

    bool flag = false;
    if(a < 0 && a != LONG_MIN)
    {
        a = -a;
        sign = -1;
    }
    else if(a == LONG_MIN)
    {
        sign = -1;
        a = LONG_MAX;
        flag = true;
    }
    if(flag)
    {
        flag = false;    
        ptr[0]+=1;
    }

    digit = 0;
    while(a)
    {
        ptr[digit++] = a % 10;
        a/=10;
    }
    digit++;

    carry();
}
ExtremeLong::ExtremeLong(long long a, int size = 50)
{
    ptr = new int[size];
    memset(ptr,0,size * sizeof(int));
    lim = size;
    sign = 1;

    bool flag = false;
    if(a < 0 && a != LONG_LONG_MIN)
    {
        a = -a;
        sign = -1;
    }
    else if(a == LONG_LONG_MIN)
    {
        sign = -1;
        a = LONG_LONG_MAX;
        flag = true;
    }
    if(flag)
    {
        flag = false;    
        ptr[0]+=1;
    }

    digit = 0;
    while(a)
    {
        ptr[digit++] = a % 10;
        a/=10;
    }
    digit++;

    carry();
}
ExtremeLong::ExtremeLong(const char* c)
{
    sign = 1;
    digit = 0;

    long long len = strlen(c);
    lim = len;

    ptr = new int[lim];
    memset(ptr,0,len * sizeof(int));

    bool flag = false;
    if(c[0] == '-')
    {
        sign = -1;
        flag = true;
    }

    for(int i = len - 1; i >= ((flag) ? 1 : 0) ;i--)
    {
        if(!isdigit(c[i]))
            throw string_err;
        ptr[digit++] = c[i] - '0';
    }
    while(ptr[digit - 1] == 0)
        digit--;
    
    if(digit == 0 && ptr[0] == 0)
    {   
        digit = 1;
        sign = 1;
    }
}
ExtremeLong::ExtremeLong(const string& s)
{
    sign = 1;
    digit = 0;

    long long len = s.length();
    lim = len;

    ptr = new int[lim];
    memset(ptr,0,len * sizeof(int));

    bool flag = false;
    if(s[0] == '-')
    {
        sign = -1;
        flag = true;
    }
    for(int i = len - 1; i >= ((flag) ? 1 : 0) ;i--)
    {
        if(!isdigit(s[i]))
            throw string_err;
    
        ptr[digit++] = s[i] - '0';
    }
    while(ptr[digit - 1] == 0)
        digit--;
    if(digit == 0 && ptr[0] == 0)
    {   
        digit = 1;
        sign = 1;
    }
}
ExtremeLong::ExtremeLong(const ExtremeLong&E)
{
    lim = E.lim;
    digit = E.digit;
    sign = E.sign;
    ptr = new int [lim];
    memset(ptr,0,E.lim * sizeof(int));
    for(int i = 0; i < digit; i++)
        ptr[i] = E.ptr[i];
}
ExtremeLong::~ExtremeLong()
{
    delete[]ptr;
}
ExtremeLong::ExtremeLong(ExtremeLong&& E)
{
    this->digit = E.digit;
    this->sign = E.sign;
    this->ptr = E.ptr;
    this->lim = E.lim;
    E.ptr = NULL;
    //cout << "构造" << endl;
}

istream& operator>>(istream& input,ExtremeLong& E)
{
    string s;
    cin>>s;
    ExtremeLong E1{s};
    cout << E1 << endl;
    E = E1;
}
ostream& operator<<(ostream& out,const ExtremeLong& E)
{
    out << ((E.sign == 1) ? "" : "-");
    for(int i = E.digit - 1; i >= 0; i--)
    {
        out << E.ptr[i];
    }
    return out;
}
ExtremeLong& ExtremeLong:: operator=(const ExtremeLong& E)
{
    lim = E.lim;
    digit = E.digit;
    sign = E.sign;
    int* temp = new int[lim];
    memset(temp,0,sizeof(temp));
    for(int i = 0; i < digit; i++)
    {
        temp[i] = E.ptr[i];
    }
    delete[] ptr;
    ptr = temp;
}
ExtremeLong& ExtremeLong::operator=(ExtremeLong&& E)
{
    
    this->ptr = E.ptr;
    this->digit = E.digit;
    this->lim = E.lim;
    this->sign = E.sign;
    
    //cout << "赋值";
    
}
ExtremeLong& ExtremeLong ::operator=(long long a)
{
    delete[] ptr;
    ptr = new int[50];
    memset(ptr,0,50 * sizeof(int));
    lim = 50;
    sign = 1;
    bool flag = false;
    if(a < 0 && a != LONG_LONG_MIN)
    {
        a = -a;
        sign = -1;
    }
    else if(a == LONG_LONG_MIN)
    {
        sign = -1;
        a = LONG_LONG_MAX;
        flag = true;
    }
    if(flag)
    {
        flag = false;    
        ptr[0]+=1;
    }

    digit = 0;
    while(a)
    {
        ptr[digit++] = a % 10;
        a/=10;
    }

    if(!digit)
    {
        digit++;
    }
    carry();
}

ExtremeLong& ExtremeLong::operator*=(const ExtremeLong&E)
{
    ExtremeLong t;

    t.resize(lim + E.digit);
    t.digit = digit + E.digit; 
    t.sign = sign * E.sign;
    for(int i = 0; i < digit; i++)
    {
        for(int j = 0; j < E.digit; j++)
        {
            t.ptr[i+j] +=  ptr[i] * E.ptr[j];
        }
        
    }
    t.carry();
    *this = t;
    return *this;
}
ExtremeLong& ExtremeLong::operator+=(const ExtremeLong& E)
{
    ExtremeLong t;
    t.resize((digit > E.digit) ? digit + 1 : E.digit + 1);
    t.digit = ((digit > E.digit) ? digit : E.digit);
    if(sign == E.sign)
    {
        t.resize((E.lim > lim) ? E.lim + 2: lim + 2);

        for(int i = 0; i < digit; i++)
        {
            t.ptr[i] += ptr[i];
        }
        for(int i = 0; i < E.digit; i++)
        {
            t.ptr[i] += E.ptr[i];
        }
    }
    else
    {
        if(digit < E.digit)
        {
            t.sign = E.sign;
            add(t,E,*this);
        }
        else if(digit > E.digit)
        {
            t.sign = sign;
            add(t,*this,E);
        }
        else
        {
            int flag = 0;
            for(int i = digit - 1; i >= 0; i--)
            {
                if(ptr[i] > E.ptr[i])
                {
                    flag = 1;
                    break;
                }
                else if(ptr[i] < E.ptr[i])
                {
                    flag = 2;
                    break;
                }
            }
            

            if(flag == 0)
            {
                *this = 0;
            }
            else if(flag == 1)
            {
                t.sign = sign;
                add(t,*this,E);
            }
            else if(flag == 2)
            {
                t.sign = E.sign;
                add(t,E,*this);
            }
        }
    }
    t.carry();
    

    *this = t;
    return *this;
    
}

int ExtremeLong::digits()const
{
    return digit;
}
int ExtremeLong::signs()const
{
    return sign;
}
int ExtremeLong::operator[](const int a)const
{
    return ptr[a];
}
void ExtremeLong::resize(long long a)
{
    int*temp = new int[a];
    memset(temp,0,a*sizeof(int));
    if(digit > a)
        digit = a;
        
    for(int i = 0; i < digit; i++)
    {
        temp[i] = ptr[i];
    }
    delete[] ptr;
    ptr = temp;
    lim = a;
    
}
void ExtremeLong::carry()
{
    digit = lim - 1;
    bool flag = false;
    while(ptr[digit] == 0 && digit >= 0)
    {
        flag = true;
        digit--;
    }
    if(flag)
        digit++;

    for(int i = 0; i < digit; i++)
    {
        if(ptr[i] >= 10)
        {
            if(i  == lim - 1)
            {
                resize(2*lim);
            }
            if(i == digit - 1)
            {
                digit++;
            }
            ptr[i + 1] += ptr[i] / 10;
            ptr[i] %= 10;
        }
    }
    for(int i = 0; i < digit; i++)
    {
        if(ptr[i] < 0)
        {
            ptr[i+1]--;
            ptr[i] += 10;
        }
    }
    
    flag = false;
    while(ptr[digit] == 0 && digit >= 0)
    {
        flag = true;
        digit--;
    }
    if(flag)
        digit++;
    if(!digit) digit = 1;
    
}
ExtremeLong ExtremeLong::abs()
{
    ExtremeLong E{*this};
    E.sign = 1;
    return E; 
}

//类外
ExtremeLong operator*(const ExtremeLong& e1,const ExtremeLong& e2)
{
    ExtremeLong e3 = e1;
    e3 *= e2;
    return e3;
}
ExtremeLong operator+(const ExtremeLong& e1,const ExtremeLong& e2)
{
    ExtremeLong e3 = e1;
    e3 += e2;
    return e3;
}
ExtremeLong operator^(const ExtremeLong& e1,const ExtremeLong& e2)
{
    if(e2 == 0)
        return e1;
    else
    {
        ExtremeLong E{e1};
        for(ExtremeLong i{1}; i < e2; i += 1)
        {
            E *= e1;
        }
        return E;
    }
}

ExtremeLong operator""xl(const char* c)
{
    return ExtremeLong(c);
}
ExtremeLong operator""XL(const char* c)
{
    return ExtremeLong(c);
}


bool operator>(const ExtremeLong& e1,const ExtremeLong& e2)
{
    if(e1.signs() > e2.signs())
        return true;
    else if(e1.signs() < e2. signs())
        return false;
    
    if(e1.signs() == 1)
    {
        if(e1.digits() > e2.digits())
            return true;
        else if(e1.digits() < e2.digits())
            return false;
        
        for(int i = e1.digits() - 1; i >= 0; i--)
        {
            if(e1[i] > e2[i])
                return true;
            else if(e1[i] < e2[i])
                return false;
        }
    }
    else if(e1.signs() == -1)
    {
        if(e1.digits() > e2.digits())
            return false;
        else if(e1.digits() < e2.digits())
            return true;
        
        for(int i = e1.digits() - 1; i >= 0; i--)
        {
            if(e1[i] > e2[i])
                return false;
            else if(e1[i] < e2[i])
                return true;
        }
    }
    return false;
}
bool operator<(const ExtremeLong& e1,const ExtremeLong& e2)
{
    if(e1.signs() > e2.signs())
        return false;
    else if(e1.signs() < e2. signs())
        return true;
    
    if(e1.signs() == 1)
    {
        if(e1.digits() > e2.digits())
            return false;
        else if(e1.digits() < e2.digits())
            return true;
        
        for(int i = e1.digits() - 1; i >= 0; i--)
        {
            if(e1[i] > e2[i])
                return false;
            else if(e1[i] < e2[i])
                return true;
        }
    }
    else if(e1.signs() == -1)
    {
        if(e1.digits() > e2.digits())
            return true;
        else if(e1.digits() < e2.digits())
            return false;
        
        for(int i = e1.digits() - 1; i >= 0; i--)
        {
            if(e1[i] > e2[i])
                return true;
            else if(e1[i] < e2[i])
                return false;
        }
    }
    return false;
}
bool operator==(const ExtremeLong&e1, const ExtremeLong&e2)
{
    if(e1.signs() != e2.signs())
        return false;
    if(e1.digits() != e2.digits())
        return false;
    for(int i = e1.digits() - 1; i >= 0; i--)
    {
        if( e1[i] != e2[i] )
        return false;
    }
    return true;
    
}
bool operator>=(const ExtremeLong& e1, const ExtremeLong& e2)
{
    return (e1 > e2) || (e1 == e2);
}
bool operator<=(const ExtremeLong& e1, const ExtremeLong& e2)
{
    return (e1 < e2) || (e1 == e2);
}
bool operator!=(const ExtremeLong& e1, const ExtremeLong& e2)
{
    return !(e1 == e2);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值