Jaka jest różnica między wartością signed i unsigned int?
c
unsigned-integer
signed-integer
Moumita Das
źródło
źródło
Odpowiedzi:
Jak zapewne wiesz,
int
s są wewnętrznie przechowywane w postaci binarnej. Zwykleint
zawiera 32 bity, ale w niektórych środowiskach może zawierać 16 lub 64 bity (lub nawet inną liczbę, zwykle, ale niekoniecznie, potęgę dwóch).Ale w tym przykładzie spójrzmy na 4-bitowe liczby całkowite. Mały, ale przydatny do celów ilustracyjnych.
Ponieważ taka liczba całkowita ma cztery bity, może przyjąć jedną z 16 wartości; 16 to 2 do czwartej potęgi, czyli 2 razy 2 razy 2 razy 2. Jakie to są wartości? Odpowiedź zależy od tego, czy ta liczba całkowita to a
signed int
czy anunsigned int
. Zunsigned int
, wartość nigdy nie jest ujemny; nie ma znaku związanego z wartością. Oto 16 możliwych wartości czterobitowychunsigned int
:bits value 0000 0 0001 1 0010 2 0011 3 0100 4 0101 5 0110 6 0111 7 1000 8 1001 9 1010 10 1011 11 1100 12 1101 13 1110 14 1111 15
... a oto 16 możliwych wartości czterobitowego
signed int
:bits value 0000 0 0001 1 0010 2 0011 3 0100 4 0101 5 0110 6 0111 7 1000 -8 1001 -7 1010 -6 1011 -5 1100 -4 1101 -3 1110 -2 1111 -1
Jak widać, dla
signed int
s najbardziej znaczący bit występuje1
wtedy i tylko wtedy, gdy liczba jest ujemna. Dlatego dlasigned int
s ten bit jest nazywany „bitem znaku”.źródło
(unsigned)(-1)
musi być maksymalną reprezentowalną wartością dlaunsigned
(niezależnie od reprezentacji binarnej), co jest trywialnie prawdziwe dla uzupełnień do 2, ale nie dla innych reprezentacji.int
iunsigned int
są dwoma różnymi typami liczb całkowitych. (int
może być również określane jakosigned int
lub po prostusigned
;unsigned int
może być również określane jakounsigned
.)Jak sugerują nazwy,
int
jest podpisana typ całkowitą, iunsigned int
jest niepodpisany typu całkowitą. Oznacza to, żeint
może reprezentować wartości ujemne iunsigned int
może przedstawiać tylko wartości nieujemne.Język C nakłada pewne wymagania na zakresy tego typu. Zakres
int
musi być co najmniej-32767
..+32767
, a zakresunsigned int
musi być co najmniej0
..65535
. Oznacza to, że oba typy muszą mieć co najmniej 16 bitów. W wielu systemach mają 32 bity, w niektórych nawet 64 bity.int
zwykle ma dodatkową wartość ujemną ze względu na reprezentację dopełnienia do dwóch używaną w większości nowoczesnych systemów.Być może najważniejszą różnicą jest zachowanie arytmetyki ze znakiem i bez znaku. W przypadku podpisanego
int
przepełnienie ma niezdefiniowane zachowanie. Bounsigned int
nie ma przelewu; każda operacja, która zwraca wartość spoza zakresu typu zawija się wokół, na przykładUINT_MAX + 1U == 0U
.Dowolny typ liczb całkowitych, ze znakiem lub bez, modeluje podzakres nieskończonego zbioru matematycznych liczb całkowitych. Dopóki pracujesz z wartościami w zakresie typu, wszystko działa. Kiedy zbliżasz się do dolnej lub górnej granicy typu, napotykasz nieciągłość i możesz uzyskać nieoczekiwane wyniki. W przypadku liczb całkowitych ze znakiem problemy występują tylko w przypadku bardzo dużych wartości ujemnych i dodatnich, przekraczających
INT_MIN
iINT_MAX
. W przypadku typów całkowitych bez znaku problemy występują przy bardzo dużych wartościach dodatnich i przy zerze . Może to być źródłem błędów. Na przykład jest to nieskończona pętla:for (unsigned int i = 10; i >= 0; i --) [ printf("%u\n", i); }
ponieważ
i
jest zawsze większe lub równe zero; taka jest natura typów bez znaku. (Wewnątrz pętli, gdyi
wynosi zero,i--
ustawia swoją wartość naUINT_MAX
.)źródło
Czasami wiemy z góry, że wartość przechowywana w danej zmiennej całkowitej będzie zawsze dodatnia - np. Gdy jest używana tylko do liczenia rzeczy. W takim przypadku możemy zadeklarować zmienną być niepodpisany, jak w,
unsigned int num student;
. Przy takiej deklaracji zakres dopuszczalnych wartości całkowitych (dla kompilatora 32-bitowego) przesunie się z zakresu od -2147483648 do +2147483647 do zakresu od 0 do 4294967295. W ten sposób zadeklarowanie liczby całkowitej jako bez znaku prawie podwaja rozmiar największego możliwego wartość, którą może utrzymać w inny sposób.źródło
W kategoriach laików bez znaku int jest liczbą całkowitą, która nie może być ujemna, a zatem ma wyższy zakres wartości dodatnich, niż może przyjąć. Wartość int ze znakiem to liczba całkowita, która może być ujemna, ale ma niższy zakres dodatni w zamian za bardziej ujemne wartości, jakie może przyjąć.
źródło
W praktyce istnieją dwie różnice:
cout
w C ++ lubprintf
C): reprezentacja bitowa w postaci liczby całkowitej bez znaku jest interpretowana jako nieujemna liczba całkowita przez funkcje drukowania.ten kod może zidentyfikować liczbę całkowitą za pomocą kryterium porządkowania:
char a = 0; a--; if (0 < a) printf("unsigned"); else printf("signed");
źródło