2010-09-28 15 views
27

Rozważ te definicje:Jaka jest różnica między unsigned int i signed int w C?

int x=5; 
int y=-5; 
unsigned int z=5; 

Jak są przechowywane w pamięci? Czy ktokolwiek może wyjaśnić bitową reprezentację tych w pamięci?

Czy int x=5 i int y=-5 mają tę samą reprezentację bitów w pamięci?

+0

To pytanie może wymagać rozdziału do opracowania. Jeśli chcesz poznać tajniki, sprawdź [Unsigned i Signed Integers] (http://kias.dyndns.org/comath/13.html), aby uzyskać więcej wyjaśnień. – anonymous

Odpowiedz

3

Oto bardzo ładne połączenie co wyjaśnia przechowywanie podpisane i unsigned int w C -

http://answers.yahoo.com/question/index?qid=20090516032239AAzcX1O pobrane z tego powyższego artykułu

-

„proces

nazywa uzupełnienie dwójkowe jest wykorzystywana do przekształcania liczby dodatnie na liczby ujemne Efektem ubocznym tego jest to, że najbardziej znaczący bit jest używany do informowania komputera, jeśli liczba jest dodatnia lub ujemna.Jeśli najważniejszym bitem jest 1, liczba jest ujemna. liczba jest dodatnia. "

+0

ok na kompilatorze 16-bitowym możesz mi powiedzieć, w jaki sposób int x = 5 i int y = 5 wewnętrznie przechowują w pamięci. Proszę podać reprezentację bitową. –

+6

Należy zauważyć, że dopełnienie 2 nie jest jedyną podpisaną reprezentacją dozwoloną dla implementacji C - dozwolone są również dopełnienie i wielkość znaku. – caf

0

Zakładając int jest liczbą całkowitą 16 bitowej (która zależy od realizacji C, w większości są 32-bitowe obecnie) reprezentacja nieco różni się jak następuje:

5 = 0000000000000101 
-5 = 1111111111111011 

jeśli binarny 1111111111111011 będzie ustawiony na unsigned int , byłby dziesiętny 65531.

+6

ISO C ma _przypisuje się do uzupełnienia do uzupełnienia 2 mandatu 2. – paxdiablo

+0

ok na 16-bitowym kompilatorze możesz mi powiedzieć, w jaki sposób int x = 5 i int y = 5 wewnętrznie przechowują w pamięci. Proszę podać reprezentację bitową –

+0

@Anand: czego tak naprawdę chcesz? w odpowiedzi znajduje się bitowa reprezentacja (w uzupełnieniu do dwóch). –

4

Parametr C standard określa, że ​​niepodpisane liczby będą przechowywane w postaci binarnej. (Z opcjonalnymi bitami wypełniającymi). Podpisane numery można przechowywać w jednym z trzech formatów: Wielkość i znak; uzupełnienie dwójki lub uzupełnienie. Co ciekawe, wyklucza niektóre inne reprezentacje, takie jak Excess-n or Base −2.

Jednak na większości maszyn i kompilatorów przechowujesz podpisane numery w uzupełnieniu do 2-ek.

int jest zwykle 16 lub 32 bitów. Standard mówi, że int powinien być najbardziej efektywny dla procesora leżącego u jego podstaw, o ile jest to >= short i <= long, to jest dozwolone przez standard.

Historia niektórych komputerów i systemów operacyjnych powoduje, że nie jest to najlepszy rozmiar dla bieżącej iteracji sprzętu.

+0

ok na 16-bitowym kompilatorze możesz mi powiedzieć, w jaki sposób int x = 5 i int y = 5 wewnętrznie przechowują w pamięci. Proszę podać reprezentację bitową –

+0

-1: Niestety twoja odpowiedź jest błędna. C określa bardzo dokładnie, w jaki sposób liczby całkowite mają być reprezentowane. W szczególności w przypadku typów bez znaku nie ma dużego wyboru dla implementacji kompilatora. Ale nawet w przypadku podpisanych typów standard jest dość restrykcyjny. Natomiast 'int' nie jest typem najbardziej wydajnym dla procesora. W większości przypadków jest obecnie zablokowany 32 bitami (tylko ze względów składniowych niż cokolwiek innego), gdzie najbardziej wydajny często jest 64. –

+0

@Jens Gustedt: "Niestety", odpowiedź Douglasa jest bardzo poprawna. Standard nie rozróżnia dopełnienia dwójki, dopełnienia ani wielkości sygnatury, stwierdza jedynie, że reprezentacje dodatnie podpisanych int muszą być identyczne z reprezentacją tych samych wartości w unsigned ints. Standard stwierdza również, że "zwykły" obiekt ** int ** ma naturalną wielkość sugerowaną przez architekturę środowiska wykonawczego ".Wdrożone implementacje nie są winą języka. Douglas ma absolutną rację, więc daję +1, aby zrekompensować twoje -1. – DevSolar

37

ISO C wskazuje na różnice.

Typ danych int jest podpisany i ma minimalny zakres od co najmniej -32767 do 32767 włącznie. Rzeczywiste wartości są podane odpowiednio w limits.h jako i .

Wartość unsigned int ma minimalny zakres od 0 do 65535 włącznie, a rzeczywista maksymalna wartość to UINT_MAX z tego samego pliku nagłówkowego.

Poza tym standard nie wymaga dwóch notacji uzupełniającej do kodowania wartości, to tylko jedna z możliwości.Trzy dozwolone typy musiałby kodowanie następujących dokumentów dla 5 i -5 (używając typów 16-bitowe dane):

 two's complement | ones' complement | sign/magnitude 
    +---------------------+---------------------+---------------------+ 
5 | 0000 0000 0000 0101 | 0000 0000 0000 0101 | 0000 0000 0000 0101 | 
-5 | 1111 1111 1111 1011 | 1111 1111 1111 1010 | 1000 0000 0000 0101 | 
    +---------------------+---------------------+---------------------+ 
  • w dwóch uzupełnień, masz ujemny z licznych odwracając wszystkie bity następnie dodanie 1.
  • W swoim uzupełnieniu otrzymuje się ujemną liczbę poprzez odwrócenie wszystkich bitów.
  • W znaku/magnitu, górny bit jest znakiem, więc po prostu odwróć to, aby uzyskać negatyw.

Należy zauważyć, że wartości dodatnie mają takie same kodowanie dla wszystkich reprezentacji, a wartości ujemne są różne.

Należy zauważyć, że dla wartości niepodpisanych nie trzeba używać jednego z bitów do znaku. Oznacza to, że masz większy zasięg po stronie dodatniej (oczywiście bez negatywnych kodowań).

I nie, 5 i -5 nie mogą mieć tego samego kodowania, niezależnie od używanej reprezentacji. W przeciwnym razie nie byłoby sposobu, by odróżnić.

+3

Wymaga to jednak wyboru dopełnienia 2, uzupełnienia lub wielkości znaku. – caf

+0

Czy implementacja zgodna może wykorzystywać tę samą reprezentację dla liczb podpisanych i niepodpisanych, a jedynie wymusić, aby bit znaku był "0" dla operacji na typach zadeklarowanych jako "unsigned" (tak, że byłby to zasadniczo "bit marginesu")? – supercat

+0

Możliwe, myślę, że to może być dozwolone, ale ponieważ minimalny zakres wynosi 0-65536, do tego schematu potrzeba co najmniej 17 bitów. To by policzyło 16-bitowe liczby całkowite bez znaku, ale prawdopodobnie byłoby w porządku z 32-bitowymi liczbami całkowitymi. Nie jestem tego pewien, ponieważ nie przyjrzałem się bliżej, czy owinięcie niepodpisane jest określone przez ISO, ale wydaje się ono nieefektywne/marnotrawne przynajmniej dla obecnego zbioru procesorów. – paxdiablo

2

Ponieważ chodzi tylko o pamięć, wszystkie wartości liczbowe są przechowywane w pamięci binarnej.

32-bitowa liczba całkowita bez znaku może zawierać wartości ze wszystkich binarnych 0s do wszystkich binarnych 1s.

Jeśli chodzi o 32-bitową liczbę całkowitą ze znakiem, oznacza to, że jeden z jej bitów (najbardziej znaczący) to flaga oznaczająca wartość dodatnią lub ujemną.

+0

Czy możesz mi powiedzieć w tym przypadku, jak sprawdzić, czy wartość podana s8 (podpisana ośmiobitowo), jeśli jest poza zakresem, czy nie. Czy powinienem porównać wartość do 0x7F zamiast 0xFF? Czy powinienem najpierw sprawdzić bit znaku? dzięki –

Powiązane problemy