2010-11-17 7 views
39

Jestem bardzo nowe do czynienia z bitów i nie utknął na następujące ostrzeżenie przy kompilacji:ostrzegawcza: lewy shift count> = szerokość typu

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

Moja linia 7 wygląda tak

unsigned long int x = 1 << 32; 

byłoby to sensowne, gdy wielkość long w moim systemie był 32 bity. Jednak sizeof(long) zwraca 8 i CHAR_BIT jest zdefiniowany jako 8 sugerując, że długi powinien być 8x8 = 64-bitowy.

Czego mi tu brakuje? Czy sizeof i CHAR_BIT są niedokładne lub czy źle zrozumiałem coś fundamentalnego?

Odpowiedz

63

long może być typu 64-bitowego, ale 1 nadal jest int. Trzeba dokonać 1 się long int pomocą L przyrostek:

unsigned long x = 1UL << 32; 

(Należy również uczynić go unsigned pomocą U sufiks jak już wykazano, aby uniknąć problemów z lewej przesuwanie podpisaną całkowitą Nie ma problemu. gdy long wynosi 64 bitów szerokości i przesunięcia o 32 bitów, lecz może to być problemem, jeśli przesunięty 63 bitów)

+0

Czy 'unsigned long x = 1; x << = 32; 'praca, w interesie? –

+0

@Kolink: Tak, miałoby to ten sam efekt, co "unsigned long" 1 << 32' Lewy operand po prostu musi być 'unsigned long'. Sufiks "UL" jest najprostszym sposobem na osiągnięcie tego. –

+0

@ James McNellis: Jakie są problemy z * _left__ przesuwaniem liczby całkowitej ze znakiem *? Wiem tylko, że *** prawo *** przesuwanie liczby całkowitej ze znakiem może prowadzić do różnych wyników z różnymi kompilatorami. – pynexj

1

unsigned long x = 1UL < < 31;

Nie wyświetlać komunikatu o błędzie. Ponieważ przed określeniem 32, nie jest prawdą, ponieważ tylko ograniczone do 0-31.

0

Nie można zmieniać wartości do jego max bit

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

Tak, to generuje ostrzeżenie

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

+0

Twoje sformułowanie jest błędne. Ty ** możesz ** przesunąć '1' na najbardziej znaczący bit tego typu, jeśli jest on' unsigned' lub jeśli jest 'signed' i ma' INT_MIN == 1 << width - 1'. Przesuwa * poza * ten najwyższy bit, który może powodować problemy. –

8

unsigned long jest 32-bitowa lub 64-bitowa, która zależy od systemu. unsigned long long jest zawsze 64-bitowy. Należy to zrobić w następujący sposób:

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

IOW, to wielkość stałej 1, która daje problemy, a nie x. – deStrangis

-1

Można użyć coś takiego:

unsigned long x = 1; 
x = x << 32; 
Powiązane problemy