Qual è la differenza tra signed e unsigned int?
Qual è la differenza tra signed e unsigned int?
Risposte:
Come probabilmente saprai, int
i messaggi di posta elettronica vengono memorizzati internamente in formato binario. Tipicamente un int
contiene 32 bit, ma in alcuni ambienti potrebbe contenere 16 o 64 bit (o anche un numero diverso, di solito ma non necessariamente una potenza di due).
Ma per questo esempio, diamo un'occhiata agli interi a 4 bit. Piccolo, ma utile a scopo illustrativo.
Poiché ci sono quattro bit in un tale numero intero, può assumere uno dei 16 valori; 16 fa da due alla quarta potenza, o 2 volte 2 volte 2 volte 2. Quali sono questi valori? La risposta dipende dal fatto che questo numero intero sia a signed int
o an unsigned int
. Con un unsigned int
, il valore non è mai negativo; non vi è alcun segno associato al valore. Ecco i 16 possibili valori di un quattro bit 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
... e Ecco i 16 possibili valori di un quattro bit 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
Come puoi vedere, per signed int
s il bit più significativo è 1
se e solo se il numero è negativo. Ecco perché, per signed int
s, questo bit è noto come "bit di segno".
(unsigned)(-1)
deve essere il valore massimo rappresentabile per unsigned
(indipendentemente dalla rappresentazione binaria), che è banalmente vero per il complemento a 2, ma non per altre rappresentazioni.
int
e unsigned int
sono due tipi interi distinti. ( int
può anche essere indicato come signed int
, o semplicemente signed
; unsigned int
può anche essere indicato come unsigned
.)
Come implica il nome, int
è un firmato tipo intero, ed unsigned int
è un unsigned tipo intero. Ciò significa che int
è in grado di rappresentare valori negativi e unsigned int
può rappresentare solo valori non negativi.
Il linguaggio C impone alcuni requisiti agli intervalli di questi tipi. La gamma di int
deve essere di almeno -32767
.. +32767
, e la gamma di unsigned int
deve essere almeno 0
.. 65535
. Ciò implica che entrambi i tipi devono essere almeno 16 bit. Sono 32 bit su molti sistemi o addirittura 64 bit su alcuni. int
tipicamente ha un valore extra negativo dovuto alla rappresentazione del complemento a due utilizzata dalla maggior parte dei sistemi moderni.
Forse la differenza più importante è il comportamento dell'aritmetica con segno rispetto a quella senza segno. Per firmato int
, l'overflow ha un comportamento indefinito. Perché unsigned int
non c'è overflow; qualsiasi operazione che restituisce un valore al di fuori dell'intervallo del tipo si avvolge, così per esempio UINT_MAX + 1U == 0U
.
Qualsiasi tipo intero, con o senza segno, modella un sottointervallo dell'insieme infinito di numeri interi matematici. Finché lavori con valori all'interno dell'intervallo di un tipo, tutto funziona. Quando ti avvicini al limite inferiore o superiore di un tipo, incontri una discontinuità e puoi ottenere risultati inaspettati. Per i tipi interi con segno, i problemi si verificano solo per valori negativi e positivi molto grandi, eccedenti INT_MIN
e INT_MAX
. Per i tipi interi senza segno, si verificano problemi per valori positivi molto grandi e pari a zero . Questa può essere una fonte di bug. Ad esempio, questo è un ciclo infinito:
for (unsigned int i = 10; i >= 0; i --) [
printf("%u\n", i);
}
perché i
è sempre maggiore o uguale a zero; questa è la natura dei tipi non firmati. (All'interno del ciclo, quando i
è zero, i--
imposta il suo valore su UINT_MAX
.)
In parole povere un int senza segno è un numero intero che non può essere negativo e quindi ha un intervallo più elevato di valori positivi che può assumere. Un int con segno è un numero intero che può essere negativo ma ha un intervallo positivo inferiore in cambio di valori più negativi che può assumere.
A volte sappiamo in anticipo che il valore memorizzato in una data variabile intera sarà sempre positivo, ad esempio quando viene utilizzato solo per contare le cose. In tal caso si può dichiarare la variabile da non firmata, come in, unsigned int num student;
. Con una tale dichiarazione, l'intervallo di valori interi consentiti (per un compilatore a 32 bit) passerà dall'intervallo -2147483648 a +2147483647 all'intervallo da 0 a 4294967295. Pertanto, dichiarare un numero intero come senza segno quasi raddoppia la dimensione del più grande possibile valore che può contenere altrimenti.
In pratica ci sono due differenze:
cout
in C ++ o printf
in C): la rappresentazione di un intero senza segno viene interpretata come un intero non negativo dalle funzioni di stampa.questo codice può identificare il numero intero utilizzando il criterio di ordinamento:
char a = 0;
a--;
if (0 < a)
printf("unsigned");
else
printf("signed");