2009-12-29 3 views
3

Je suis en train de faire un calcul mathématique extrême extrême de très grand/petit nombre. Le très grand nombre peut avoir 10 - 50 chiffres et le très petit nombre peut avoir 10 - 50 décimales. Est-ce que C++ peut le faire? Sinon, existe-t-il un autre langage de programmation capable de gérer ce type de numéro?Extreme grand/petit numéro de programmation

+0

quelque peu lié: http://stackoverflow.com/questions/1653131/what-programming-language-will-enable-me-to-enter-a- very-long-number-without-conv – jldupont

+1

"Extrêmement précis" et "virgule flottante" ne vont pas nécessairement ensemble. http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems –

Répondre

10

C++ peut le faire avec une bibliothèque, par exemple la bibliothèque GNU Multiple Precision Arithmetic.

+1

excellent pointeur, +1 –

+0

J'ai téléchargé la bibliothèque arithmétique multi-précision GNU (4.3.1) du site. Comment est-ce que j'installe cela? J'utilise Visual Studio 2008. – yihangho

+2

@yihang répondu ici. http: // stackoverflow.com/questions/1017058/building-gmp-library-with-visual-studio –

1

Chaque langue peut gérer de tels nombres si vous implémentez correctement le type de données. Je pense que vous voulez un langage qui a un tel type de données intégré. En règle générale, pour le fonc- tionnement du type de données double en C++, ainsi que dans la plupart des autres langages, la précision est très bonne pour les très petits et très grands nombres. Je recommande de consulter wikipedia à ce sujet, il est très bien expliqué là.

La seule question qui reste est, si un double a assez de précision pour vous. 50 chiffres seraient trop difficiles à gérer, mais vous pouvez toujours implémenter votre propre type de données. Puisque vous savez maintenant comment fonctionne le double, cela devrait être possible. Cependant, vous pouvez toujours essayer de rechercher une bibliothèque mathématique ayant un tel type de données déjà implémenté.

+0

En tant que kludge avant de recourir à une bibliothèque de précision arbitraire, le type de données 'long double' pourrait fonctionner pour l'OP s'il est assez grand. –

0

Je pense que python (http://python.org) et ruby ​​(http://ruby-lang.org) ont tous deux un support pour les très grands et très petits nombres comme ça, vous pourriez leur donner un coup d'oeil. En outre, les deux sont interopérables avec C++.

Espérons que cela aide.

1

Si vous voulez faire arithmétique très précis, par opposition à l'écriture du code C++ pour faire de l'arithmétique très précis, vous devriez regarder Mathematica, Maple et leur concours open-source tels que Maxima, Sage, et probablement d'autres .

+0

C'est un bon point. –

1

De nombreuses langues prennent en charge des nombres arbitrairement grands, y compris (par ordre alphabétique) Haskell, Icon, Python, Scheme et Smalltalk, entre autres. Le support pour de très petits nombres est plus rare, à moins que ce que vous voulez soit une arithmétique rationnelle exacte. Si vos calculs sur de très petits nombres doivent être exacts, alors je pense que l'arithmétique rationnelle exacte est votre seule alternative, mais elle devient rapidement chère. Votre autre option consiste à coder votre propre arithmétique à virgule flottante avec beaucoup plus de chiffres de précision que ceux fournis par une unité matérielle à virgule flottante. Pour cela, vous avez besoin d'un calcul en nombres entiers, qui en C ou C++ peut être fourni par la bibliothèque GNU GMP ou par la bibliothèque C Interfaces and Implementations de Dave Hanson. Si vous souhaitez essayer une autre langue en plus de C++, je vous recommande d'utiliser Haskell, car il dispose de très bonnes fonctionnalités pour créer de nouveaux types numériques, et vous pouvez utiliser QuickCheck pour tester vos types numériques automatiquement, ce qui est un temps énorme -saver et bug-finder.

0

Vous pouvez utiliser des chaînes, c'est lent mais précis. Ici, ont ce code plus je l'ai fait ...

string add(string a, string b){ 
     if(b[0]-'0' == 0 && b.length() == 1){ 
      return a;  
     } 
     int len = max(a.length(), b.length())+1; 
     int ar[len]; 
     int br[len]; 
     int buffer[len]; 

     for(int i = 0; i < len; i++){ 
      ar[i] = 0; 
      br[i] = 0; 
      buffer[i] = 0; 
     } 

     for(int i = 0; i < a.length(); i++){ 
      ar[i] = a[a.length()-i-1]-'0'; 
     } 


     for(int i = 0; i < b.length(); i++){ 
      br[i] = b[b.length()-i-1]-'0';  
     } 

     // Now we need to add the numbers and add them to the buffer: 

     for(int i = 0; i < len-1; i++){ 
      buffer[i] = ar[i]+br[i]; 
     } 

     for(int i = 0; i < len-1; i++){ 
      if(buffer[i] > 9){ 
       string temp = convertInt(buffer[i]); 
       int first_int = temp[0]-'0'; 
       int second_int = temp[1]-'0'; 
       buffer[i+1] = buffer[i+1]+first_int; 
       buffer[i] = second_int;  
      }  
     } 


     stringstream r; 
     bool num_before = false; 
     for(int i = len-1; i >= 0; i--){ 
      if(buffer[i] == 0 && num_before){ 
       r << buffer[i]; 
      } else if(buffer[i] != 0 && num_before == false){ 
       r << buffer[i]; 
       num_before = true; 
      } else if(buffer[i] != 0 && num_before){ 
       r << buffer[i]; 
      } 
     } 

     return r.str(); 
    } 

string convertInt(int number) 
{ 
    stringstream ss;//create a stringstream 
    ss << number;//add number to the stream 
    return ss.str();//return a string with the contents of the stream 
}