Qual è la differenza tra signed e unsigned int


94

Qual è la differenza tra signed e unsigned int?


5
Questa è una vera domanda e la risposta non è così semplice ma piuttosto sottile.
R .. GitHub SMETTA DI AIUTARE ICE

Votazioni per riaprire. Potrebbe essere un duplicato, ma è sicuramente una vera domanda.
Brian


Dovrebbero essere aggiunti più tag, poiché vengono utilizzati da molte lingue.
Juan Boero

Questa domanda potrebbe richiedere un capitolo per essere elaborata. Se vuoi conoscere i dettagli, controlla Numeri interi non firmati e firmati per ulteriori spiegazioni.
anonimo

Risposte:


115

Come probabilmente saprai, inti messaggi di posta elettronica vengono memorizzati internamente in formato binario. Tipicamente un intcontiene 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 into 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:

... e Ecco i 16 possibili valori di un quattro bit signed int:

Come puoi vedere, per signed ints il bit più significativo è 1se e solo se il numero è negativo. Ecco perché, per signed ints, questo bit è noto come "bit di segno".


11
Forse vale la pena sottolineare che questo è il formato del complemento a due, che è certamente ampiamente utilizzato al giorno d'oggi. Ci sono anche altri modi per rappresentare interi con segno, in particolare il proprio complemento.
Schedler

Corretta. E lo standard ISO9899 C non richiede nemmeno l'uso del complemento a uno o a due; qualsiasi altra convenzione che funziona effettivamente è consentita.
Bill Evans a Mariposa

1
Sebbene il complemento a due non sia richiesto, (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.
rubenvb

3
@BillEvansatMariposa: Lo standard dice che per interi con segno ci sono 3 rappresentazioni consentite: segno + magnitudine, complemento a 2, complemento a 1. Qualsiasi altro dovrebbe essere invisibile al programma ed essere percepito come uno di questi 3.
Alexey Frunze

Ok ma sotto il cofano! Cosa sta succedendo VERAMENTE! Qual è la differenza tra un numero FIRMATO e UNSIGNED! Come la macchina gestisce il calcolo? Sottrae solo un valore da un altro? Come differisce 1111 = 15 e 1111 = -1?
Mihail Georgescu

19

inte unsigned intsono due tipi interi distinti. ( intpuò anche essere indicato come signed int, o semplicemente signed; unsigned intpuò 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 intpuò rappresentare solo valori non negativi.

Il linguaggio C impone alcuni requisiti agli intervalli di questi tipi. La gamma di intdeve essere di almeno -32767.. +32767, e la gamma di unsigned intdeve 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. inttipicamente 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 intnon 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_MINe 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:

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.)


14

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.


12

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.


@Alex Ero nel mezzo della modifica di quella risposta 10 minuti fa ed è identica. lol
Skuld

0

In pratica ci sono due differenze:

  1. stampa (ad es. con coutin C ++ o printfin C): la rappresentazione di un intero senza segno viene interpretata come un intero non negativo dalle funzioni di stampa.
  2. ordinazione : l'ordine dipende dalle specifiche firmate o non firmate.

questo codice può identificare il numero intero utilizzando il criterio di ordinamento:


Se questo spiega il diverso con uno che tratta numeri negativi e l'altro, no. Aiuterebbe molto questo post.
Daniel Jackson,

@DanielJackson Non è chiaro quello che dici. un carattere può essere considerato negativo o positivo a seconda del compilatore. l'output del codice dipende da cosa sceglie il compilatore e questo mostra la differenza tra firmato e non firmato.
Minimus Heximus
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.