如何表示大数?

问题描述 投票:0回答:10

在 C++ 中处理大数字输入的最佳方法是什么(例如

10^100
)?

对于算法,我通常切换到 ruby,有时使用字符串。

还有其他好的方法吗?

c++ biginteger bigint largenumber arbitrary-precision
10个回答
16
投票

听起来您正在寻找一种输入任意精度数字的方法。 您可以使用以下两个库:GMPMAPM


11
投票

查看 Owen Astrachan 的 C++ 中的大整数案例研究.pdf。我发现这个文件非常有用,有详细的介绍和代码实现。它不使用任何第三方库。我已经用它来处理巨大的数字(只要你有足够的内存来存储

vector<char>
),没有任何问题。


想法: 它通过将 big int 存储在

vector<char>
中来实现任意精度整数类。

vector<char> myDigits; // stores all digits of number

那么所有与big int相关的操作,包括

<<, >>, +, -, *, ==, <, !=, >, etc.
,都可以基于这个
char array
进行操作。


代码品味: 这是头文件,你可以在pdf文件中找到它的cpp和代码。

#include <iostream>
#include <string> // for strings
#include <vector> // for sequence of digits
using namespace std;

class BigInt
{
public:
    BigInt(); // default constructor, value = 0
    BigInt(int); // assign an integer value
    BigInt(const string &); // assign a string
    // may need these in alternative implementation
    // BigInt(const BigInt &); // copy constructor
    // ~BigInt(); // destructor
    // const BigInt & operator = (const BigInt &);
    // assignment operator
    // operators: arithmetic, relational
    const BigInt & operator += (const BigInt &);
    const BigInt & operator -= (const BigInt &);
    const BigInt & operator *= (const BigInt &);
    const BigInt & operator *= (int num);
    string ToString() const; // convert to string
    int ToInt() const; // convert to int
    double ToDouble() const; // convert to double
    // facilitate operators ==, <, << without friends
    bool Equal(const BigInt & rhs) const;
    bool LessThan(const BigInt & rhs) const;
    void Print(ostream & os) const;
private:
    // other helper functions
    bool IsNegative() const; // return true iff number is negative
    bool IsPositive() const; // return true iff number is positive
    int NumDigits() const; // return # digits in number
    int GetDigit(int k) const;
    void AddSigDigit(int value);
    void ChangeDigit(int k, int value);
    void Normalize();
    // private state/instance variables
    enum Sign{positive,negative};
    Sign mySign; // is number positive or negative
    vector<char> myDigits; // stores all digits of number
    int myNumDigits; // stores # of digits of number
};

// free functions
ostream & operator <<(ostream &, const BigInt &);
istream & operator >>(istream &, BigInt &);
BigInt operator +(const BigInt & lhs, const BigInt & rhs);
BigInt operator -(const BigInt & lhs, const BigInt & rhs);
BigInt operator *(const BigInt & lhs, const BigInt & rhs);
BigInt operator *(const BigInt & lhs, int num);
BigInt operator *(int num, const BigInt & rhs);
bool operator == (const BigInt & lhs, const BigInt & rhs);
bool operator < (const BigInt & lhs, const BigInt & rhs);
bool operator != (const BigInt & lhs, const BigInt & rhs);
bool operator > (const BigInt & lhs, const BigInt & rhs);
bool operator >= (const BigInt & lhs, const BigInt & rhs);
bool operator <= (const BigInt & lhs, const BigInt & rhs);

7
投票

如果您希望为此目的编写自己的代码,请尝试使用字符串来存储大数字...然后您可以在它们上创建基本操作,例如 + - / *...例如 -

#include <iostream>

using namespace std;

string add (string &s1, string &s2){
    int carry=0,sum,i;

    string  min=s1,
    max=s2,
    result = "";

    if (s1.length()>s2.length()){
        max = s1;
        min = s2;
    } else {
        max = s2;
        min = s1;
    }

    for (i = min.length()-1; i>=0; i--){
        sum = min[i] + max[i + max.length() - min.length()] + carry - 2*'0';

        carry = sum/10;
        sum %=10;

        result = (char)(sum + '0') + result;
    }

    i = max.length() - min.length()-1;

    while (i>=0){
        sum = max[i] + carry - '0';
        carry = sum/10;
        sum%=10;

        result = (char)(sum + '0') + result;
        i--;
    }

    if (carry!=0){
        result = (char)(carry + '0') + result;
    }       

    return result;
}

int main (){
    string a,b;

    cin >> a >> b;

    cout << add (a,b)<<endl;

    return 0;
}

6
投票

您是否正在寻找如何对收到的大量输入执行操作?有一个大整数C++库(类似于Java),允许您执行算术运算...


3
投票

假设您正在谈论输入数字,双精度将使您达到 1.7976931348623157 x 10^308


3
投票

您可能想看看 gmplib,一个用于 C 和 C++ 的任意精度数字处理库


3
投票

如果你希望它准确,你需要一个处理大数字的库。 Java 拥有 BigInt,无论您想要获取多少位数字,它总是准确的,并提供对它们的数学运算。所有源代码都包含在内,您可以转移它,但这确实不是 C++ 最擅长的事情——我会使用基于 JVM 的语言并使用 Big 库之一。

我认为我不会为此使用 ruby,除非你希望它变慢,并且我假设既然你在谈论 C++,速度在某种程度上是一个设计考虑因素。


2
投票

正如其他人已经指出的那样,C++ 中有各种 bignum/任意精度库,您可能会发现它们很有用。如果速度不是必需的,我的印象是 Python 和 Lisp 都默认使用 bignum。


0
投票

考虑 boost::cpp_int

#include <boost/multiprecision/cpp_int.hpp>
#include <iostream>

int main()
{
   using namespace boost::multiprecision;

   cpp_int u = 1;
   for(unsigned i = 1; i <= 100; ++i)
      u *= i;

   // prints 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000 (i.e. 100!)
   std::cout << u << std::endl;

   return 0;
}

-3
投票

我认为进行此类算术计算的最佳方法是使用字符串。将输入作为命令行参数,然后使用

atoi()
itoa()
等字符串函数操作整个逻辑!但是,嘿,这可以用于乘法和除法吗?我认为通过这种方式,输入的字符串
strlen
对于编译器的编程并不重要,直到逻辑良好为止。

© www.soinside.com 2019 - 2024. All rights reserved.