2010-11-17 10 views
39

Je suis très nouveau pour traiter les bits et ont obtenu collé sur l'avertissement suivant lors de la compilation:avertissement: nombre de décalage à gauche> = largeur du type

7: warning: left shift count >= width of type 

Ma ligne 7 ressemble à ceci

unsigned long int x = 1 << 32; 

Cela serait logique si la taille de long sur mon système était 32 bits. Cependant, sizeof(long) renvoie 8 et CHAR_BIT est défini comme 8, ce qui suggère que long devrait être 8x8 = 64 bits de long.

Qu'est-ce que je manque ici? Est-ce que sizeof et CHAR_BIT sont inexacts ou ai-je mal compris quelque chose de fondamental?

Répondre

63

long peut être un type 64 bits, mais 1 est toujours un int. Vous devez faire 1 un long int en utilisant le suffixe L:

unsigned long x = 1UL << 32; 

(Vous devez également faire unsigned en utilisant le suffixe U comme je l'ai montré, pour éviter les problèmes de gauche le déplacement d'un entier signé Il n'y a aucun problème. lorsqu'un long a une largeur de 64 bits et que l'on décale de 32 bits, mais que l'on déplaçait 63 bits, cela poserait un problème)

+0

Est-ce que 'unsigned long x = 1; x << = 32; 'travail, par intérêt? –

+0

@Kolink: Oui, cela aurait le même effet, comme le ferait '(unsigned long) 1 << 32' L'opérande de gauche doit simplement être un' unsigned long'. Le suffixe 'UL' est juste le moyen le plus simple d'accomplir cela. –

+0

@ James McNellis: Quels sont les problèmes de __left__ * déplaçant un entier signé *? Je sais seulement que *** right *** déplacer un entier signé peut conduire à un résultat différent avec des compilateurs différents. – pynexj

1

non signé long x = 1UL < < 31;

Ne pas afficher le message d'erreur. Car avant de spécifier le 32, n'est pas vrai car seulement limité à 0-31.

0

Vous ne pouvez pas changer une valeur à son bit max

int x;   // let int be 4 bytes so max bits : 32 
x <<= 32; 

Donc, cela génère l'avertissement

left shift count >= width of type (i.e type = int = 32)

+0

Votre formulation est erronée. Vous ** pouvez ** déplacer un '1' sur le bit le plus significatif de son type, s'il est' unsigned' ou s'il est 'signed' et a' INT_MIN == 1 << width - 1'. Il se déplace * au-delà * du bit le plus élevé qui peut causer des problèmes. –

8

unsigned long est 32 bits ou 64 bits qui dépend de votre système. unsigned long long est toujours 64 bits. Vous devriez le faire comme suit:

unsigned long long x = 1ULL << 32 
+1

IOW, c'est la taille de la constante 1 qui vous pose problème, pas de x. – deStrangis

-1

Vous pouvez utiliser quelque chose comme ça:

unsigned long x = 1; 
x = x << 32; 
Questions connexes