簡體   English   中英

在 C++ 中處理大數?

[英]Handling large numbers in C++?

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

對於算法,我通常切換到 ruby​​,有時我會使用字符串。

還有什么好的方法嗎?

聽起來你正在尋找一種輸入任意精度數字的方法。 這里有兩個你可以使用的庫: GMPMAPM

查看C ++中的大整數案例研究.pdf by Owen Astrachan。 我發現這個文件對於詳細介紹和代碼實現非常有用。 它不使用任何第三方庫。 我用它來處理大量數字(只要你有足夠的內存來存儲vector<char> )沒有問題。


想法 :它通過在vector<char>存儲big int來實現任意精度整數類。

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);

您在尋找如何對您收到的大型輸入執行操作嗎? 有一個大整數C ++庫(類似於Java),允許您執行算術運算......

如果您希望為此目的制作自己的代碼,請嘗試使用字符串存儲大數字...然后您可以在它們上創建基本操作,例如+ - / * ...例如 -

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

假設你在談論輸入數字,雙精度會讓你達到1.7976931348623157 x 10 ^ 308

您可能希望了解gmplib ,它是C和C ++的任意精確數字處理庫

如果你想要它准確,你需要一個庫來處理大數字。 Java有BigInt,無論你想要多少位數,它總是准確的,並提供它們的數學運算。 包含所有源代碼,你可以傳輸它,但這確實不是C ++最擅長的事情 - 我使用基於JVM的語言並使用其中一個Big庫。

我不認為我會使用ruby,除非你想讓它變慢,我假設因為你在談論C ++,速度在某種程度上是設計考慮因素。

正如其他人已經指出的那樣,C ++中有各種各樣的bignum /任意精度庫,你可能會發現它們很有用。 如果不需要速度,我的印象是Python和Lisp都默認使用bignums。

考慮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;
}

我認為進行這種算術運算的最佳方法是使用字符串。 輸入作為命令行參數,然后使用像atoi()itoa()這樣的字符串函數來操作整個邏輯! 但是,嘿,這可以用於乘法和除法嗎? 我認為這樣輸入的strlen字符串對編譯器編程無關緊要,直到邏輯正常。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM