Jaka jest różnica między wartością signed i unsigned int?
Jaka jest różnica między wartością signed i unsigned int?
Odpowiedzi:
Jak zapewne wiesz, ints są wewnętrznie przechowywane w postaci binarnej. Zwykle intzawiera 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 intczy an unsigned int. Z unsigned int, wartość nigdy nie jest ujemny; nie ma znaku związanego z wartością. Oto 16 możliwych wartości czterobitowych unsigned 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 ints najbardziej znaczący bit występuje 1wtedy i tylko wtedy, gdy liczba jest ujemna. Dlatego dla signed ints ten bit jest nazywany „bitem znaku”.
(unsigned)(-1)musi być maksymalną reprezentowalną wartością dla unsigned(niezależnie od reprezentacji binarnej), co jest trywialnie prawdziwe dla uzupełnień do 2, ale nie dla innych reprezentacji.
inti unsigned intsą dwoma różnymi typami liczb całkowitych. ( intmoże być również określane jako signed intlub po prostu signed; unsigned intmoże być również określane jako unsigned.)
Jak sugerują nazwy, intjest podpisana typ całkowitą, i unsigned intjest niepodpisany typu całkowitą. Oznacza to, że intmoże reprezentować wartości ujemne i unsigned intmoże przedstawiać tylko wartości nieujemne.
Język C nakłada pewne wymagania na zakresy tego typu. Zakres intmusi być co najmniej -32767.. +32767, a zakres unsigned intmusi być co najmniej 0.. 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. intzwykle 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 intprzepełnienie ma niezdefiniowane zachowanie. Bo unsigned intnie ma przelewu; każda operacja, która zwraca wartość spoza zakresu typu zawija się wokół, na przykład UINT_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_MINi INT_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ż ijest zawsze większe lub równe zero; taka jest natura typów bez znaku. (Wewnątrz pętli, gdy iwynosi zero, i--ustawia swoją wartość na UINT_MAX.)
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.
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ąć.
W praktyce istnieją dwie różnice:
coutw C ++ lub printfC): 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");