2016-02-19 3 views
3

Je me demande comment changer la valeur à gauche en C++. Par exemple:Décalage C++ à gauche avec une grande valeur

1 << 180 

et je beleve que résultat de ce devrait être:

1532495540865888858358347027150309183618739122183602176 

(testé en python [1 < < 180]);

+7

C++ n'a pas de type natif d'une longueur de 180 bits. Le plus grand est "long long", qui est habituellement de seulement 64 bits. Si vous avez besoin d'une arithmétique de précision arbitraire, utilisez une bibliothèque "bignum" comme [GMP] (https://gmplib.org/). Pour une bibliothèque C++, regardez [Boost multiprecision] (http://www.boost.org/doc/libs/1_60_0/libs/multiprecision/doc/html/index.html). –

+0

Peut-être une refonte du code pour savoir pourquoi vous avez besoin de stocker de tels grands nombres/modèles de bits –

Répondre

5

Python prend en charge l'arithmétique de précision arbitraire, mais pas C++.

En outre, conformément à la norme [expr.shift]:

Le comportement est indéfini si l'opérande droit est négatif, ou plus ou égale à la longueur en bits de la promotion gauche opérande.

Pour utiliser les grands entiers en C++ vous pouvez utiliser la bibliothèque Boost, qui fournit des emballages à différentes bibliothèques avec de longues implémentations arithmétiques:

#include <boost/multiprecision/gmp.hpp> 
#include <iostream> 

int main() 
{ 
    boost::multiprecision::mpz_int one(1); 
    std::cout << (one << 180) << std::endl; 
    return 0; 
} 

Prints

1532495540865888858358347027150309183618739122183602176 
0

Les entiers (ou longs) sont stockés en 32 bits et ne peuvent donc pas être décalés de 180. Si vous avez besoin de la valeur exacte, essayez d'écrire/télécharger une classe qui gère les grands entiers. Sinon, utilisez un pow double et appel (2,180). Il a une précision de 0f 15 chiffres

+0

Il n'y a aucune garantie que les entiers sont stockés dans des unités de 32 bits. Sur un système 64 bits, ils sont stockés dans des unités 64 bits. La norme définit uniquement la plage d'un nombre entier, pas sa taille implémentée. Pour les entiers spécifiques à la taille, il existe les types 'intxx_t' et' uintxx_t'. –

+0

Un double est un mauvais choix car il a un nombre limité de bits dans la mantisse et perd de la précision pour les grandes valeurs, telles que 'pow (2,180)'. De même, d'autres points flottants ont le même problème. Rappelez-vous que les valeurs à virgule flottante sont représentées par trois éléments: Sign, Mantissa et Exponent. –

1

En C++ (comme en C) un décalage vers la gauche d'une valeur supérieure au nombre de bits du type d'opérande décalé donne un comportement non défini.

Dans ce cas, vous déplacez une valeur int qui a probablement 32 bits de taille restante d'une valeur supérieure à 32, le comportement n'est donc pas défini.

Si vous devez traiter des entiers plus grands que la taille des mots sur votre machine, vous aurez probablement besoin d'utiliser une bibliothèque. GMP est une option.

6

Vous pouvez le faire utilisant un std::bitset:

std::bitset<200> bits = 1; // 200 bits long 
bits <<= 180; 

L'utilité dépend de ce que vous voulez en faire. Il ne peut pas être converti en un seul type prédéfini car il n'est pas assez grand. Mais il existe d'autres opérations potentiellement utiles qui peuvent être effectuées sur elle.