在C++中功率非常大

Power very large number in C++

本文关键字:非常 功率 C++      更新时间:2023-10-16

有一点时间的人可以向我解释一下非常大的数字是如何密集的吗?我在这里谈论的不是现成的解决方案,以及如何实现算术的唯一解释。理想情况下,它基于类 std::string。

@edit

我读了一些关于班次的东西,但示例只是以列表的形式,我想解释一下它是如何工作的。

您可以将一个大数字表示为某个基数中的数字序列,并分别表示数字的符号。要做算术,您只需实现您在小学学到的算法来执行加法、长乘法等。有更有效的算法(例如Karatsuba)来执行一些操作,但初始实现可以使用更简单的形式。

如果你真的必须使用 std::string,你可以使用第一个字符来存储符号("+"或"-"),然后是 ascii 中以 10 为基数的数字。它效率不高,但也许是一种简单的入门方法,而且它肯定会使打印数字变得容易。

这是我

在需要时快速写的东西(不记得什么时候)。是的:

  1. 马车;
  2. 不完整;
  3. 每个数组元素任意使用 3 位数字,而可以使用更多;
  4. 可以明显改进(欢迎任何评论^^)。

但是,我希望这会以某种方式有用。

typedef long long int lli;
class BigInt
{
public: // Methods
    BigInt(lli s) : m_nbElements(100)
    {
        m_number.resize(m_nbElements);
        for (lli i=0; i < m_nbElements; ++i)
        {
            m_number[i] = s%1000;
            s /= 1000;
        }
    }
    BigInt(const std::string &str) : m_nbElements(100)
    {
        m_number.resize(m_nbElements);
        size_t sizeStr = str.size();
        int i = str.size() - 1;
        int thousands = 0;
        for (; i >= 2; i -= 3, ++thousands)
        {
            std::string subStr = str.substr(i-2, 3);
            unsigned int value;
            std::istringstream(subStr) >> value;
            m_number[thousands] = value;
        }
        // Handle the "first" 1 or 2 digits
        if (i >= 0)
        {
            std::string subStr = str.substr(0, i+1);
            unsigned int value;
            std::istringstream(subStr) >> value;
            m_number[thousands] = value;
        }
    }
    BigInt operator*(lli s)
    {
        lli temp, remainder = 0;
        for (lli i=0; i < m_nbElements; ++i)
        {
            temp = m_number[i] * s + remainder;
            m_number[i] = temp % 1000;
            remainder = temp / 1000;
        }
        return (*this);
    }
    BigInt operator/(lli s)
    {
        lli temp, remainder = 0;
        for (int i=m_nbElements-1; i >= 0; --i)
        {
            temp = (m_number[i] + remainder) / s;
            remainder = (m_number[i] % s)*1000;
            m_number[i] = temp;
        }
        return (*this);
    }
    BigInt operator-(BigInt s)
    {
        lli temp;
        for (unsigned int i=0; i < m_nbElements; ++i)
        {
            temp = m_number[i] - s.m_number[i];
            if (temp < 0)
            {
                --m_number[i+1];
                temp += 1000;
            }
            m_number[i] = temp;
        }
        return (*this);
    }
    BigInt operator+(BigInt s)
    {
        lli temp, remainder = 0;
        for (lli i=0; i < m_nbElements; ++i)
        {
            temp = m_number[i] + s.m_number[i] + remainder;
            m_number[i] = temp % 1000;
            remainder = temp / 1000;
        }
        return (*this);
    }
    std::string ToString()
    {
        std::string result = "";
        bool significantDigitsFound = false;
        for (int i=m_nbElements-1; i >= 0 ; --i)
        {
            if (!significantDigitsFound)
            {
                if (m_number[i] > 0)
                {
                    std::ostringstream ss;
                    ss << m_number[i];
                    result = ss.str();
                    significantDigitsFound = true;
                }
            }
            else
            {
                std::ostringstream ss;
                ss << std::setw(3) << std::setfill( '0' ) << m_number[i];
                result += ss.str();
            }
        }
        if (result == "")
        {
            result = "0";
        }
        return result;
    }
private: // Attributes
    int m_nbElements;
    std::vector<lli> m_number;
};