C++ 大数类

看了加法得做法

我看还行 转载:https://blog.csdn.net/qq_20200047/article/details/89483458

ClassBigInteger.h

#ifndef CLASSBIGINT
#define CLASSBIGINT
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
class BigInteger
{
public:
    BigInteger();
    BigInteger(const BigInteger&);
    BigInteger(std::string num1);
    BigInteger(char num1);
    ~BigInteger();
private:
    std::string _num1;
public:

    //静态方法
    static int compare(std::string num1, std::string num2);//if num1 > num2, return 1, else if num1 = num2,return 0,else return -1;
    static std::string add(std::string num1, std::string num2);//num1 + num2
    static std::string minus(std::string num1, std::string num2);//num1 - num2
    static std::string multiply(std::string num1, std::string num2);//num1 * num2
    static std::string divide(std::string num1, std::string num2, int floatpoint);//num1 / snum2
    static std::string mod(std::string num1, std::string num2);//num1 mod num2
    static std::string gcd(std::string num1, std::string num2);//gcd(num1,num2)
    static std::string exgcd(std::string a, std::string b, std::string& x, std::string& y);//if gcd(a,b)=1,a*x+b*y=1,return gcd(a,b),x is inverse of a

    //重载操作符
    std::string toString() const;
    void init();
    void setnum(std::string);
    BigInteger operator+(const BigInteger&);//+
    BigInteger operator-(const BigInteger&);//-
    BigInteger operator*(const BigInteger&);//*
    BigInteger operator/(const BigInteger&);///
    BigInteger operator%(const BigInteger&);//mod
    bool operator==(const BigInteger&)const;//==
    bool operator>(const BigInteger&)const;//>
    bool operator<(const BigInteger&)const;//<
};

#endif CLASSBIGINT

ClassBigInteger.cpp

#include "ClassBigInteger.h"
#include <string>
#include <algorithm>
#include <openssl/rsa.h>
using namespace std;
BigInteger::BigInteger()
{

}

BigInteger::BigInteger(std::string num1) :_num1(num1)
{

}

BigInteger::BigInteger(char num1)
{
    std::string cc = "";
    cc += num1;
    _num1 = cc;
}

BigInteger::BigInteger(const BigInteger& bi)
{
    _num1 = bi._num1;
}

BigInteger::~BigInteger()
{

}

void BigInteger::setnum(std::string c) {
    this->_num1 += c;
}

void BigInteger::init() {
    this->_num1 = "";
}

std::string BigInteger::toString() const
{
    return _num1;
}

BigInteger BigInteger::operator+(const BigInteger& bi)
{
    BigInteger t(*this);
    t._num1 = add(t._num1, bi._num1);
    return t;
}

BigInteger BigInteger::operator-(const BigInteger& bi)
{
    BigInteger t(*this);
    t._num1 = minus(t._num1, bi._num1);
    return t;
}

BigInteger BigInteger::operator*(const BigInteger& bi)
{
    BigInteger t(*this);
    t._num1 = multiply(t._num1, bi._num1);
    return t;
}

BigInteger BigInteger::operator/(const BigInteger& bi)
{
    BigInteger t(*this);
    t._num1 = divide(t._num1, bi._num1, 0);
    return t;
}

BigInteger BigInteger::operator%(const BigInteger& bi)
{
    BigInteger t(*this);
    t._num1 = mod(t._num1, bi._num1);
    return t;
}

int BigInteger::compare(std::string number1, std::string number2)
{
    if (number1[0] != '-' && number2[0] != '-') {
        int j;
        int length1 = number1.size();
        int length2 = number2.size();

        if (number1.size() == 0)
            number1 = "0";
        if (number2.size() == 0)
            number2 = "0";

        j = 0;
        for (int i = 0; i < length1; ++i)
        {
            if (number1[i] == '0')
                ++j;
            else
                break;
        }
        number1 = number1.substr(j);
        j = 0;
        for (int i = 0; i < length2; ++i)
        {
            if (number2[i] == '0')
                ++j;
            else
                break;
        }
        number2 = number2.substr(j);
        length1 = number1.size();
        length2 = number2.size();
        if (length1 > length2)
        {
            return 1;
        }
        else if (length1 == length2)
        {
            if (number1.compare(number2) > 0)
            {
                return 1;
            }
            else if (number1.compare(number2) == 0)
            {
                return 0;
            }
            else
            {
                return -1;
            }
        }
        else
        {
            return -1;
        }
    }
    else if (number1[0] == '-' && number2[0] != '-')
    {
        return -1;
    }
    else if (number1[0] != '-' && number2[0] == '-')
    {
        return 1;
    }
    else {
        std::string absnumber1 = number1.substr(1);
        std::string absnumber2 = number2.substr(1);
        int result = compare(absnumber1, absnumber2);
        if (result == 1)
        {
            return -1;
        }
        else if (result == -1)
        {
            return 1;
        }
        else
        {
            return 0;
        }
    }
}

bool BigInteger::operator==(const BigInteger& a)const {
    std::string s1 = this->toString();
    std::string s2 = a.toString();
    if (this->compare(s1, s2) == 0)return true;
    else return false;
}

bool BigInteger::operator>(const BigInteger& a)const {
    std::string s1 = this->toString();
    std::string s2 = a.toString();
    if (this->compare(s1, s2) == 1)return true;
    else return false;
}

bool BigInteger::operator<(const BigInteger& a)const {
    std::string s1 = this->toString();
    std::string s2 = a.toString();
    if (this->compare(s1, s2) == -1)return true;
    else return false;
}

std::string BigInteger::add(std::string number1, std::string number2)
{
    if (number1[0] != '-' && number2[0] != '-') {
        int i;
        int length1 = number1.size();
        int length2 = number2.size();

        std::string result = "";

        reverse(number1.begin(), number1.end());
        reverse(number2.begin(), number2.end());

        for (i = 0; i < length1 && i < length2; i++)
        {
            char c = (char)(number1[i] + number2[i] - 48);//每一位相加,-48减去ascii的'0'
            result = result + c;//把结果给result
        }

        //加上剩余比较长的数
        while (i < length1)
        {
            result = result + number1[i];
            ++i;
        }

        while (i < length2)
        {
            result = result + number2[i];
            ++i;
        }

        //转化 之前只是相加  但是没有进位  现在进位 
        int carry = 0;
        for (i = 0; i < (int)result.size(); ++i)
        {
            int value = result[i] - 48 + carry;
            result[i] = (char)(value % 10 + 48);
            carry = value / 10;
        }

        //最后一次也要进位
        if (carry != 0)
        {
            result = result + (char)(carry + 48);
        }

        for (i = result.size() - 1; i >= 0; i--)
        {
            if (result[i] != '0')
                break;
        }

        //截取有效位,有的数前面是用0来填充的
        result = result.substr(0, i + 1);
        //翻转回来
        reverse(result.begin(), result.end());
        if (result.length() == 0)
            result = "0";
        return result;
    }
    else if (number1[0] == '-' && number2[0] != '-') {
        std::string absnumber1 = "";
        for (size_t i = 1; i < number1.size(); i++)
        {
            absnumber1 += number1[i];
        }
        std::string result = minus(number2, absnumber1);
        return result;
    }
    else if (number1[0] != '-' && number2[0] == '-') {
        std::string absnumber2 = "";
        for (size_t i = 1; i < number2.size(); i++)
        {
            absnumber2 += number2[i];
        }
        std::string result = minus(number1, absnumber2);
        return result;
    }
    else
    {
        std::string absnumber1 = number1.substr(1);
        std::string absnumber2 = number2.substr(1);
        return "-" + add(absnumber1, absnumber2);
    }
}

std::string BigInteger::minus(std::string number1, std::string number2)
{
    if (number1[0] != '-' && number2[0] != '-') {
        int i;
        std::string result = "";

        int length1 = number1.size();
        int length2 = number2.size();

        if (compare(number2, number1) > 0)
        {
            return "-" + minus(number2, number1);
        }

        reverse(number1.begin(), number1.end());
        reverse(number2.begin(), number2.end());

        for (i = 0; i < length1 && i < length2; i++)
        {
            char c = number1[i] - number2[i] + 48;
            result = result + c;
        }

        if (i < length1)
        {
            for (; i < length1; i++)
            {
                result = result + number1[i];
            }
        }

        int carry = 0;
        for (i = 0; i < (int)result.length(); i++)
        {
            int value = result[i] - 48 + carry;
            if (value < 0)
            {
                value = value + 10;
                carry = -1;
            }
            else
                carry = 0;
            result[i] = (char)(value + 48);
        }

        for (i = result.size() - 1; i >= 0; i--)
        {
            if (result[i] != '0')break;
        }

        result = result.substr(0, i + 1);

        reverse(result.begin(), result.end());
        if (result.length() == 0) result = "0";
        return result;
    }
    else if (number1[0] == '-' && number2[0] != '-') {
        std::string absnumber1 = "";
        for (size_t i = 1; i < number1.size(); i++)
        {
            absnumber1 += number1[i];
        }
        std::string result = add(number2, absnumber1);
        return "-" + result;
    }
    else if (number1[0] != '-' && number2[0] == '-') {
        std::string absnumber2 = "";
        for (size_t i = 1; i < number2.size(); i++)
        {
            absnumber2 += number2[i];
        }
        std::string result = add(number1, absnumber2);
        return result;
    }
    else
    {
        std::string absnumber1 = "";
        std::string absnumber2 = "";
        for (size_t i = 1; i < number1.size(); i++)
        {
            absnumber1 += number1[i];
        }
        for (size_t i = 1; i < number2.size(); i++)
        {
            absnumber2 += number2[i];
        }
        return minus(absnumber2, absnumber1);
    }
}

std::string BigInteger::multiply(std::string number1, std::string number2)
{
    if (number1[0] != '-' && number2[0] != '-') {
        int i, j;
        int* iresult;
        int length1 = number1.size();
        int length2 = number2.size();
        std::string result = "";

        reverse(number1.begin(), number1.end());
        reverse(number2.begin(), number2.end());

        iresult = (int*)malloc(sizeof(int) * (length1 + length2 + 1));
        memset(iresult, 0, sizeof(int) * (length1 + length2 + 1));

        for (i = 0; i < length1; i++)
        {
            for (j = 0; j < length2; j++)
            {
                iresult[i + j] += ((number1[i] - 48) * (number2[j] - 48));
            }
        }

        int carry = 0;
        for (i = 0; i < length1 + length2; i++)
        {
            int value = iresult[i] + carry;
            iresult[i] = value % 10;
            carry = value / 10;
        }

        for (i = length1 + length2 - 1; i >= 0; i--)
        {
            if (iresult[i] != 0)
                break;
        }

        for (; i >= 0; i--)
        {
            result = result + (char)(iresult[i] + 48);
        }

        free(iresult);

        if (result == "") result = "0";
        return result;
    }
    else if (number1[0] == '-' && number2[0] != '-') {
        std::string absnumber1 = "";
        for (size_t i = 1; i < number1.size(); i++)
        {
            absnumber1 += number1[i];
        }
        std::string result = multiply(number2, absnumber1);
        return "-" + result;
    }
    else if (number1[0] != '-' && number2[0] == '-') {
        std::string absnumber2 = "";
        for (size_t i = 1; i < number2.size(); i++)
        {
            absnumber2 += number2[i];
        }
        std::string result = multiply(number1, absnumber2);
        return "-" + result;
    }
    else
    {
        std::string absnumber1 = "";
        std::string absnumber2 = "";
        for (size_t i = 1; i < number1.size(); i++)
        {
            absnumber1 += number1[i];
        }
        for (size_t i = 1; i < number2.size(); i++)
        {
            absnumber2 += number2[i];
        }
        return multiply(absnumber2, absnumber1);
    }
}

std::string BigInteger::divide(std::string number1, std::string number2, int floatpoint = 0)
{
    if (number1[0] != '-' && number2[0] != '-') {
        int i, j, pos;
        std::string result = "";
        std::string tempstr = "";
        int length1 = number1.size();
        int length2 = number2.size();

        if ((compare(number2, number1) > 0) && (floatpoint == 0))
        {
            return "0";
        }

        tempstr = number1.substr(0, length2);
        pos = length2 - 1;

        while (pos < length1)
        {
            int quotient = 0;
            while (compare(tempstr, number2) >= 0)
            {
                quotient++;
                tempstr = minus(tempstr, number2);
            }

            result = result + (char)(quotient + 48);
            pos++;
            if (pos < length1)
            {
                tempstr += number1[pos];
            }
        }

        if (floatpoint > 0)
        {
            result += '.';
            std::string stmp = "1";
            int itmp = 0;
            for (int k = 0; k < floatpoint; ++k)
            {
                stmp += '0';
                if (compare(multiply(minus(number1, multiply(divide(number1, number2), number2)), stmp), number2) < 0)
                {
                    result += '0';
                    ++itmp;
                }
            }

            std::string temp = divide(multiply(minus(number1, multiply(divide(number1, number2), number2)), stmp), number2);
            if (temp[0] != '0') result += temp;
        }

        j = result.size();
        for (i = 0; i < j; i++)
        {
            if (result[i] != '0') break;
        }

        result = result.substr(i, j);

        return result;
    }
    else if (number1[0] == '-' && number2[0] != '-') {
        std::string absnumber1 = "";
        for (size_t i = 1; i < number1.size(); i++)
        {
            absnumber1 += number1[i];
        }
        std::string result = divide(absnumber1, number2);
        return "-" + result;
    }
    else if (number1[0] != '-' && number2[0] == '-') {
        std::string absnumber2 = "";
        for (size_t i = 1; i < number2.size(); i++)
        {
            absnumber2 += number2[i];
        }
        std::string result = divide(number1, absnumber2);
        return "-" + result;
    }
    else
    {
        std::string absnumber1 = "";
        std::string absnumber2 = "";
        for (size_t i = 1; i < number1.size(); i++)
        {
            absnumber1 += number1[i];
        }
        for (size_t i = 1; i < number2.size(); i++)
        {
            absnumber2 += number2[i];
        }
        return divide(absnumber1, absnumber2);
    }
}

std::string BigInteger::mod(std::string number1, std::string number2)
{
    if (compare(number1, number2) == 0)
    {
        return "0";
    }
    else if (number2[0] == '-')
    {
        return "error";
    }
    else {
        std::string result = minus(number1, multiply(divide(number1, number2), number2));
        if (compare("0", result) > 0)
        {
            result = add(result, number2);
        }
        return result;
    }
}

std::string BigInteger::gcd(std::string num1, std::string num2)
{
    if (num1 == "0")
    {
        return num2;
    }
    if (num2 == "0")
    {
        return num1;
    }
    if (compare(num1, num2) == 0)
    {
        std::string temp = num1;
        num1 = num2;
        num2 = temp;
    }

    std::string result = mod(num1, num2);
    while (result != "0")
    {
        num1 = num2;
        num2 = result;
        result = mod(num1, num2);
    }
    return num2;
}

std::string BigInteger::exgcd(std::string a, std::string b, std::string& x, std::string& y)
{
    if (b == "0") {
        x = "1";
        y = "0";
        return a;
    }
    else {
        std::string x1, y1;
        if (mod(a, b) == "error")
        {
            return "error";
        }
        std::string d = exgcd(b, mod(a, b), x1, y1);
        x = y1;
        std::string temp = divide(a, b);
        std::string temp2 = multiply(temp, y1);
        y = minus(x1, temp2);
        return d;
    }
}
原文地址:https://www.cnblogs.com/Galesaur-wcy/p/15059840.html