在 C++ 中处理大数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/117429/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 12:58:41  来源:igfitidea点击:

Handling large numbers in C++?

c++bigintegerlargenumber

提问by kasperasky

What is the best way to handle large numeric inputs in C++ (for example 10^100)?

在 C++ 中处理大型数字输入的最佳方法是什么(例如10^100)?

For algorithms I usually switch over to ruby and I sometimes use strings.

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

Any other good methods?

还有什么好的方法吗?

回答by hometoast

It sounds like you're looking for a way to enter Arbitrary Precision numbers. here are two libraries you could use: GMPand MAPM

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

回答by herohuyongtao

Check out The Large Integer Case Study in C++.pdfby Owen Astrachan. I found this file extremely useful with detail introduction and code implementation. It doesn't use any 3rd-party library. I have used this to handle huge numbers (as long as you have enough memory to store vector<char>) with no problems.

查看Owen Astrachan 的C++.pdf 中的大整数案例研究。我发现这个文件在详细介绍和代码实现方面非常有用。它不使用任何 3rd 方库。我已经用它来处理大量数字(只要你有足够的内存来存储vector<char>),没有任何问题。



Idea: It implements an arbitrary precision integer class by storing big int in a vector<char>.

想法:它通过将 big int 存储在 a 中来实现任意精度整数类vector<char>

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

Then all operations related to the big int, including <<, >>, +, -, *, ==, <, !=, >, etc., can be done based on operations on this char array.

然后所有与 big int 相关的操作,包括<<, >>, +, -, *, ==, <, !=, >, etc.,都可以基于对 this 的操作来完成char array



Taste of the code: Here is the header file, you can find its cpp with codes in the pdf file.

代码味道:这里是头文件,你可以在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);

回答by Swati

Are you looking for how to perform operations on the large inputs you receive? There is a big integer C++library (similar to Java) that allows you to perform arithmetic operations...

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

回答by Abhishek Mishra

If you wish to make your own code for the purpose try using strings to store big numbers... you can then create basic ops like + - / * on them... for example -

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

#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;
}

回答by Bill K

If you want it to be accurate, you need a library made to deal with big numbers. Java has BigInt that will always be accurate no matter how many digits you want to take it to, and provides math operations on them. All the source code is included, you could transfer it, but this really isn't the kind of thing C++ is best at--I'd use a JVM based language and use one of the Big libraries.

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

I don't think I'd use ruby for this unless you wanted it to be slow, and I'm assuming that since you are talking about C++, speed is somewhat of a design consideration.

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

回答by Sergio Acosta

You might want to have a look to gmplib, an arbitrary precision number handling library for C and C++

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

回答by shoosh

assuming you are talking about inputting numbers, double precision would get you up to 1.7976931348623157 x 10^308

假设你在谈论输入数字,双精度会让你达到 1.7976931348623157 x 10^308

回答by donair

As others have already pointed out, there are various bignum/arbitrary precision libraries in C++ that you would likely find useful. If speed isn't necessary, I'm under the impression that Python and Lisp both use bignums by default.

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

回答by Ashik

Well I think the best way to do such arithmetic calculation is by using strings. Give input as command line arguments and then manipulate the whole logic using string functions like atoi()and itoa()! But, hey can this be done for multiplication and Division? I think in this way strlenof strings entered doesn't matter for programming for compiler until the logic is fine.

好吧,我认为进行此类算术计算的最佳方法是使用字符串。将输入作为命令行参数提供,然后使用atoi()itoa()!等字符串函数操作整个逻辑。但是,嘿,这可以用于乘法和除法吗?我认为以这种方式strlen输入的字符串对于编译器编程无关紧要,直到逻辑正常为止。