Обработка больших чисел в C ++? - PullRequest
18 голосов
/ 23 сентября 2008

Каков наилучший способ обработки больших числовых входов в C ++ (например, 10^100)?

Для алгоритмов я обычно переключаюсь на ruby ​​и иногда использую строки.

Любые другие хорошие методы?

Ответы [ 9 ]

15 голосов
/ 23 сентября 2008

Похоже, вы ищете способ ввода чисел произвольной точности. Вот две библиотеки, которые вы можете использовать: GMP и MAPM

7 голосов
/ 24 декабря 2013

Ознакомьтесь с Пример большого целого на C ++. Pdf от Оуэна Астрахана Я нашел этот файл чрезвычайно полезным с подробным введением и реализацией кода. Он не использует стороннюю библиотеку. Я использовал это для обработки огромных чисел (если у вас достаточно памяти для хранения vector<char>) без проблем.


Идея : Он реализует целочисленный класс с произвольной точностью, сохраняя big int в vector<char>.

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

Тогда все операции, связанные с большим int, включая <<, >>, +, -, *, ==, <, !=, >, etc., могут выполняться на основе операций с этим char array.


Вкус кода : Вот файл заголовка, вы можете найти его cpp с кодами в файле PDF.

#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);
6 голосов
/ 23 сентября 2008

Вы ищете, как выполнять операции с большими входами, которые вы получаете? Существует большая целочисленная библиотека C ++ (аналогичная Java), которая позволяет выполнять арифметические операции ...

5 голосов
/ 30 октября 2008

Если вы хотите создать собственный код для этой цели, попробуйте использовать строки для хранения больших чисел ... затем вы можете создать базовые операции, такие как + - / * для них ... например -

#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;
}
3 голосов
/ 23 сентября 2008

Если вы хотите, чтобы он был точным, вам нужна библиотека, созданная для работы с большими числами. Java имеет BigInt, который всегда будет точным независимо от того, сколько цифр вы хотите взять, и предоставляет математические операции над ними. Весь исходный код включен, вы можете передать его, но на самом деле это не то, в чем лучше C ++ - я бы использовал язык на основе JVM и одну из больших библиотек.

Я не думаю, что я бы использовал ruby ​​для этого, если бы вы не хотели, чтобы он был медленным, и я предполагаю, что, поскольку вы говорите о C ++, скорость в некотором смысле является соображением дизайна.

3 голосов
/ 23 сентября 2008

Возможно, вы захотите взглянуть на gmplib , библиотеку обработки произвольной точности чисел для C и C ++

3 голосов
/ 23 сентября 2008

при условии, что вы говорите о вводе чисел, двойная точность даст вам 1.7976931348623157 x 10 ^ 308

2 голосов
/ 23 сентября 2008

Как уже отмечали другие, в C ++ существуют различные библиотеки bignum / произвольной точности, которые вы, вероятно, сочтете полезными. Если скорость не нужна, у меня сложилось впечатление, что Python и Lisp по умолчанию используют bignums.

0 голосов
/ 09 октября 2010

Ну, я думаю, что лучший способ сделать такое арифметическое вычисление - использовать строки. Введите входные данные в качестве аргументов командной строки, а затем управляйте всей логикой, используя строковые функции, такие как atoi() и itoa()! Но, эй, это можно сделать для умножения и деления? Я думаю, что таким образом strlen введенных строк не имеет значения для программирования для компилятора, пока логика не будет в порядке.

...