2017-08-14 11 views
1

Supposons que j'ai une entrée de numéro de chaîne longue dans c++. et nous devons faire des opérations numériques dessus. Nous devons convertir ceci en integer ou n'importe quelle manière possible de faire des opérations, quelles sont ces?Comment convertir de grandes chaînes de nombres en entiers en C++?

string s="12131313123123213213123213213211312321321321312321213123213213"; 
+2

Étant donné qu'un tel nombre ne tient pas « réguliers » types entiers, vous devez soit réimplémenter les opérations que vous vous avez besoin, ou utilisez un bibliothèque bignum. –

Répondre

0

Si la chaîne contient le numéro est inférieur à std::numeric_limits<uint64_t>::max(), alors std::stoull() est la meilleure opinion.

unsigned long long = std::stoull(s); 

C++11 et plus tard.

2

Votre meilleur moyen serait d'utiliser une bibliothèque de calcul de grands nombres.

L'un des meilleurs là-bas est le GNU Multiple Precision Arithmetic Library

Exemple d'une fonction utile pour résoudre votre problème ::

Function: int mpz_set_str (mpz_t rop, const char *str, int base)

Définissez la valeur de ROP de str, un caractère nul chaîne C terminée dans la base base. L'espace blanc est autorisé dans la chaîne et est simplement ignoré.

La base peut varier de 2 à 62, ou si la base est 0, alors les premiers caractères sont utilisés : 0x et 0X pour hexadécimal, 0b et 0B pour binaire, 0 pour octal, décimal ou autrement.

Pour les bases jusqu'à 36, le cas est ignoré; les lettres majuscules et minuscules ont la même valeur. Pour les bases 37 à 62, les lettres majuscules représentent les 10,35 habituelles tandis que les lettres minuscules représentent 36,61. Cette fonction renvoie 0 si la chaîne entière est un nombre valide dans la base baseSinon, il renvoie -1.

Documentation: https://gmplib.org/manual/Assigning-Integers.html#Assigning-Integers

2

On dirait que les chiffres que vous souhaitez traiter sont ainsi grand pour tout type entier standard, donc juste « conversion », il ne vous donnera pas beaucoup. Vous avez deux options: (Hautement recommandé)

  1. Utilisez un grand entier bibliothèque comme par exemple gmp. De telles bibliothèques fournissent également des fonctions pour l'analyse et le formatage des grands nombres. Mettez en œuvre vos grands nombres vous-même, par exemple. utilisez un tableau de uintmax_t pour les stocker. Vous devrez mettre en œuvre toutes sortes d'arithmétiques dont vous pourriez avoir besoin vous-même, et ce n'est pas une tâche facile. Pour l'analyse du nombre, vous pouvez utiliser une implémentation inversée double dabble.Par exemple, voici un code que j'ai écrit il y a un moment en C, vous pouvez probablement l'utiliser tel quel, mais vous devez fournir quelques fonctions auxiliaires et vous pouvez le réécrire en utilisant des fonctionnalités C++ comme std::string et en remplaçant le struct utilisé ici avec un std::vector - il est juste ici pour documenter le concept

    typedef struct hugeint 
    { 
        size_t s;  // number of used elements in array e 
        size_t n;  // number of total elements in array e 
        uintmax_t e[]; 
    } hugeint; 
    
    hugeint *hugeint_parse(const char *str) 
    { 
        char *buf; 
    
        // allocate and initialize: 
        hugeint *result = hugeint_create(); 
    
        // this is just a helper function copying all numeric characters 
        // to a freshly allocated buffer: 
        size_t bcdsize = copyNum(&buf, str); 
    
        if (!bcdsize) return result; 
    
        size_t scanstart = 0; 
        size_t n = 0; 
        size_t i; 
        uintmax_t mask = 1; 
    
        for (i = 0; i < bcdsize; ++i) buf[i] -= '0'; 
    
        while (scanstart < bcdsize) 
        { 
         if (buf[bcdsize - 1] & 1) result->e[n] |= mask; 
         mask <<= 1; 
         if (!mask) 
         { 
          mask = 1; 
          // this function increases the storage size of the flexible array member: 
          if (++n == result->n) result = hugeint_scale(result, result->n + 1); 
         } 
         for (i = bcdsize - 1; i > scanstart; --i) 
         { 
          buf[i] >>= 1; 
          if (buf[i-1] & 1) buf[i] |= 8; 
         } 
         buf[scanstart] >>= 1; 
         while (scanstart < bcdsize && !buf[scanstart]) ++scanstart; 
         for (i = scanstart; i < bcdsize; ++i) 
         { 
          if (buf[i] > 7) buf[i] -= 3; 
         } 
        } 
    
        free(buf); 
        return result; 
    }