2008-09-22 4 views
14

Wie kann man große numerische Eingaben in C++ am besten handhaben (zum Beispiel 10^100)?Umgang mit großen Zahlen in C++?

Für Algorithmen wechsle ich normalerweise zu Ruby und manchmal verwende ich Strings.

Andere gute Methoden?

+0

Ich machte einen Versuch, ein wenig zu klären. Fühlen Sie sich frei, mich zu korrigieren, wenn ich –

+0

Danksohn fehlinterpretierte. Danke für die Bibliothek .. aber ich würde gerne wissen, gibt es in einer anderen Methode, es zu tun ?. ich meine, ohne spezifische stl 's dafür zu benutzen .. ich habe verkettete Liste benutzt !! – kasperasky

Antwort

3

vorausgesetzt, Sie sprechen, die Eingabe von Zahlen mit doppelter Genauigkeit möchten Sie 1,7976931348623157 x aufstehen 10^308

6

Suchen Sie nach wie Operationen an den großen Eingaben durchzuführen Sie erhalten? Es gibt eine big integer C++ Bibliothek (ähnlich wie Java), die Sie arithmetische Operationen durchführen kann ...

3

Sie vielleicht einen Blick auf gmplib, eine Zahl beliebige Genauigkeit Handling-Bibliothek für C haben wollen und C++

14

Es klingt als ob du nach einer Möglichkeit suchst, Arbitrary Precision Nummern einzugeben. Hier sind zwei Bibliotheken, die Sie verwenden könnten: GMP und MAPM

3

Wenn Sie wollen, dass es genau ist, benötigen Sie eine Bibliothek gemacht, um mit großen Zahlen umzugehen. Java verfügt über BigInt, das immer genau ist, egal wie viele Ziffern Sie verwenden möchten, und bietet mathematische Operationen für sie. Der gesamte Quellcode ist enthalten, Sie könnten ihn übertragen, aber das ist wirklich nicht die Art von Sache, in der C++ am besten ist - ich würde eine JVM-basierte Sprache verwenden und eine der großen Bibliotheken verwenden.

Ich glaube nicht, dass ich Ruby dafür verwenden würde, wenn Sie wollten, dass es langsam ist, und ich nehme an, dass, da Sie über C++ sprechen, Geschwindigkeit eine Designüberlegung ist.

2

Wie bereits erwähnt, gibt es in C++ verschiedene bignum/arbitrary precision-Bibliotheken, die Sie wahrscheinlich nützlich finden würden. Wenn Geschwindigkeit nicht notwendig ist, habe ich den Eindruck, dass Python und Lisp beide Bignums standardmäßig verwenden.

+0

Das ist richtig für Liso. Wenn ich Bignum Sachen mache, rolle ich mit Lisp. :) –

+0

@Paul Nathan > Das ist richtig für Liso. Meinst du Lisp? oder ist Liso eine Bibliothek, die mir nicht bekannt ist? – chollida

4

Wenn Sie Ihren eigenen Code für den Zweck zu machen versuchen Strings mit großen Zahlen speichern ... Sie können dann grundlegende ops erstellen wie + -/* auf sie ... zum Beispiel -

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

Nun, ich denke, der beste Weg, eine solche arithmetische Berechnung durchzuführen, ist die Verwendung von Strings. Geben Sie die Eingabe als Befehlszeilenargumente ein und bearbeiten Sie dann die gesamte Logik mithilfe von Zeichenfolgenfunktionen wie atoi() und itoa()! Aber kann das für Multiplikation und Division gemacht werden? Ich denke, auf diese Weise strlen der eingegebenen Strings spielt keine Rolle für die Programmierung für Compiler, bis die Logik in Ordnung ist.

+1

Dies ist keine gute Lösung. Wenn Sie Eingaben von Befehlszeilenargumenten erhalten, wird Ihr Programm unbrauchbar, wenn Sie nicht eine Art Befehlszeilenrechner erstellen. Außerdem wird bei Verwendung von 'ato *' -Funktionen davon ausgegangen, dass Sie den gewünschten Datentyp bereits kennen und dass diese im Standardpräzisionsbereich liegen. Es macht also keinen Sinn, Zeit zu verschwenden, anstatt direkt in Ihr großes Zahlenformat zu konvertieren Sie müssten diese Zahlen noch einmal analysieren, vorausgesetzt, Sie haben sie sogar richtig gelesen. 'itoa' ist ebenfalls nicht Teil der C++ - Standardbibliothek. – GraphicsMuncher

7

Schauen Sie sich The Large Integer Case Study in C++.pdf von Owen Astrachan. Ich fand diese Datei sehr nützlich mit Detaileinführung und Code-Implementierung. Es verwendet keine Bibliothek von Drittanbietern. Ich habe das verwendet, um große Zahlen (solange Sie genug Speicher haben, um vector<char> zu speichern) ohne Probleme zu handhaben.


Idea: Es implementiert eine beliebige ganzzahlige Genauigkeit Klasse von großen int in einem vector<char> speichern.

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

Dann werden alle auf die große int bezogene Operationen, einschließlich <<, >>, +, -, *, ==, <, !=, >, etc., kann basierend auf Operationen auf diesem char array erfolgen.


Geschmack des Codes: Hier ist die Header-Datei ist, wird seine CPP mit den Codes in der pdf-Datei finden.

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