2008-09-22 12 views
14

Quelle est la meilleure façon de gérer les grandes entrées numériques en C++ (par exemple 10^100)?Gestion de grands nombres en C++?

Pour les algorithmes, je passe généralement au ruby ​​et j'utilise parfois des chaînes.

Autres bonnes méthodes?

+0

J'ai essayé de clarifier un peu. N'hésitez pas à me corriger si j'ai mal interprété –

+0

merci monsieur. merci pour la bibliothèque .. mais j'aimerais savoir s'il existe une autre méthode pour le faire. je veux dire sans utiliser de stl spécifique pour cela .. j'ai utilisé la liste chaînée !! – kasperasky

Répondre

3

en supposant que vous parlez d'entrer des chiffres, double précision vous obtiendrait jusqu'à 1,7976931348623157 x 10^308

6

Vous cherchez comment effectuer des opérations sur les grandes entrées que vous recevez? Il y a une bibliothèque big integer C++ (similaire à Java) qui vous permet d'effectuer des opérations arithmétiques ...

3

Vous pouvez jeter un oeil à gmplib, une bibliothèque arbitraire de manutention numéro de précision pour C et C++

14

Il semble comme si vous cherchiez un moyen d'entrer des nombres arbitraires de précision. Voici deux bibliothèques que vous pouvez utiliser: GMP et MAPM

3

Si vous voulez que ce soit précis, vous avez besoin d'une bibliothèque faite pour traiter les grands nombres. Java a BigInt qui sera toujours précis, peu importe le nombre de chiffres que vous voulez prendre, et fournit des opérations mathématiques sur eux. Tout le code source est inclus, vous pouvez le transférer, mais ce n'est vraiment pas le genre de chose que C++ est le meilleur - j'utiliserais un langage basé sur JVM et utiliserais l'une des grandes bibliothèques. Je ne pense pas que j'utiliserais ruby ​​pour cela à moins que vous ne vouliez que ce soit lent, et je suppose que puisque vous parlez de C++, la vitesse est un peu un facteur de conception.

2

Comme d'autres l'ont déjà souligné, il existe diverses bibliothèques de précision bignum/arbitraires en C++ que vous pourriez trouver utiles. Si la vitesse n'est pas nécessaire, j'ai l'impression que Python et Lisp utilisent tous les deux des bignums par défaut.

+0

C'est correct pour Liso. Si je fais du bignum, je roule avec Lisp. :) –

+0

@Paul Nathan > C'est correct pour Liso. Voulez-vous dire Lisp? Ou Liso est-il une bibliothèque que je ne connais pas? – chollida

4

Si vous souhaitez faire votre propre code dans le but essayez d'utiliser des chaînes pour stocker de grands nombres ... vous pouvez créer ops de base comme + -/* sur eux ... par exemple -

#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

Eh bien, je pense que la meilleure façon de faire un tel calcul arithmétique est en utilisant des chaînes. Donnez une entrée en tant qu'arguments de ligne de commande, puis manipulez toute la logique à l'aide des fonctions de chaîne telles que atoi() et itoa()! Mais, hé, cela peut-il être fait pour la multiplication et la division? Je pense de cette façon strlen des chaînes entrées n'a pas d'importance pour la programmation pour le compilateur jusqu'à ce que la logique est bonne.

+1

Ce n'est pas une bonne solution. Obtenir des entrées à partir d'arguments de ligne de commande rend votre programme inutile, sauf si vous faites une sorte de calculatrice en ligne de commande. De plus, l'utilisation des fonctions 'ato *' présuppose que vous connaissez déjà le type de données désiré ET qu'elles soient dans la plage de précision standard, donc cela ne sert à rien de perdre du temps à les convertir directement en grand nombre vous devrez juste analyser à nouveau ces nombres, en supposant que vous les avez lus correctement. 'itoa' ne fait pas non plus partie de la bibliothèque C++ standard. – GraphicsMuncher

7

Découvrez The Large Integer Case Study in C++.pdf par Owen Astrachan. J'ai trouvé ce fichier extrêmement utile avec l'introduction des détails et l'implémentation du code. Il n'utilise aucune bibliothèque tierce. J'ai utilisé ceci pour gérer des nombres énormes (tant que vous avez assez de mémoire pour stocker vector<char>) sans problèmes.


Idée: Il met en œuvre une classe entière de précision arbitraire en stockant grand int dans un vector<char>.

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

Ensuite, toutes les opérations liées au grand int, y compris <<, >>, +, -, *, ==, <, !=, >, etc., peut se faire en fonction des opérations sur ce char array.


Goût du code: Voici le fichier d'en-tête, vous pouvez trouver son cpp avec des codes dans le fichier 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); 
Questions connexes