zoukankan      html  css  js  c++  java
  • 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;
        }
    }
  • 相关阅读:
    跨站的艺术-XSS Fuzzing 的技巧
    腾讯云数据库团队:PostgreSQL TOAST技术理解
    Git commit message和工作流规范
    前端识别验证码思路分析
    Akamai在内容分发网络中的算法研究(翻译总结)
    Nginx网站使用CDN之后禁止用户真实IP访问的方法
    常用机器性能评估工具
    解决关于ArcGIS10.2服务手动启动的问题
    林业通用平台上线
    土地承包经营权地块示意图打印
  • 原文地址:https://www.cnblogs.com/Galesaur-wcy/p/15059840.html
Copyright © 2011-2022 走看看