15 Domanda: Interi firmati o non firmati

domanda creata a Fri, Oct 31, 2014 12:00 AM

Sono corretto nel dire che la differenza tra un intero con segno e senza segno è:

  1. Unsigned può contenere un valore positivo più grande e nessun valore negativo.
  2. Unsigned utilizza il bit iniziale come parte del valore, mentre la versione firmata utilizza il left-most-bit per identificare se il numero è positivo o negativo.
  3. gli interi con segno possono contenere sia numeri positivi che negativi.

Qualche altra differenza?

    
362
  1. Perché 0 non è né positivo né negativo , è più appropriato utilizzare il termine valore non negativo anziché valore positivo per gli interi senza segno.
    2017-05-19 05: 50: 06Z
15 risposte                              15                         
  

Unsigned può contenere un valore positivo più grande e nessun valore negativo.

Sì.

  

Unsigned usa il bit iniziale come parte del valore, mentre la versione firmata usa il left-most-bit per identificare se il numero è positivo o negativo.

Ci sono diversi modi per rappresentare interi con segno. Il modo più semplice per visualizzare è utilizzare il bit più a sinistra come bandiera ( segno e grandezza ), ma più comune è complemento a due . Entrambi sono in uso nella maggior parte dei microprocessori moderni: il punto mobile utilizza il segno e la magnitudine, mentre l'aritmetica dei numeri interi utilizza il complemento a due.

  

gli interi con segno possono contenere sia numeri positivi che negativi.

Si

    
315
2018-12-27 22: 46: 08Z
  1. + 1 per il collegamento all'articolo del Wiki.
    2008-10-29 18: 43: 13Z
  2. Pagina 44 di questo documento PDF ha una spiegazione eccellente. cs.utexas.edu/~jason777/Programming/Connect%20Four/...
    2016-03-30 03: 11: 53Z
  3. @ Greg link is broken
    2017-03-30 13: 43: 25Z
  4. Non sono sicuro se questo è esattamente quel testo ma ho trovato un altro link. Vai alla 9 ° pagina del PDF (è in realtà la 38 ° pagina del libro) e puoi vedere la sezione chiamata Rappresentazione dei dati (Sezione 1.3). Ha la spiegazione di tutte le cose dette sopra. lms.uop.edu.jo/LMS /pluginfile.php /2420 /mod_resource /content /1 /...
    2018-05-13 16: 05: 56Z

Entrerò nelle differenze a livello di hardware, su x86. Questo è per lo più irrilevante a meno che non si stia scrivendo un compilatore o usando il linguaggio assembly. Ma è bello saperlo.

In primo luogo, x86 ha il supporto nativo per la rappresentazione del complemento a due di numeri firmati. È possibile utilizzare altre rappresentazioni, ma ciò richiederebbe più istruzioni e in genere comporterebbe uno spreco di tempo del processore.

Che cosa intendo per "supporto nativo"? Fondamentalmente intendo che ci sono una serie di istruzioniusi per i numeri non firmati e un altro set che usi per i numeri firmati. I numeri non firmati possono risiedere negli stessi registri dei numeri firmati, e in effetti puoi mischiare istruzioni firmate e non firmate senza preoccuparti del processore. Spetta al compilatore (o al programmatore dell'assembly) tenere traccia di se un numero è firmato o meno, e utilizzare le istruzioni appropriate.

In primo luogo, i numeri del complemento a due hanno la proprietà che l'addizione e la sottrazione sono la stessa cosa dei numeri senza segno. Non fa differenza se i numeri sono positivi o negativi. (Quindi vai avanti e ADD e SUB i tuoi numeri senza preoccupazioni.)

Le differenze iniziano a mostrare quando si tratta di confronti. x86 ha un modo semplice per differenziarli: sopra /sotto indica un confronto senza segno e maggiore /minore di indica un confronto firmato. (Ad es. JAE significa "Salta se sopra o uguale" e non ha segno.)

Ci sono anche due serie di istruzioni di moltiplicazione e divisione per gestire interi con segno e senza segno.

Infine: se vuoi controllare, ad esempio, un overflow, lo faresti diversamente per i numeri firmati e per i numeri non firmati.

    
89
2014-06-11 09: 16: 55Z
  1. Cosa intendi per numeri non firmati e firmati, quello che voglio chiedere è se scrivo unsigned int a = 2 e firmato int b = 2, quindi sono entrambi firmato o non firmato, un numero firmato o non firmato dipende dal tipo a cui lo assegniamo o dipende dal fatto che abbia o meno un segno negativo? Questo mi ha infastidito per un po '.
    2016-12-30 06: 07: 59Z
  2. @ SurajJain firmato e non firmato si riferiscono ai tipi. Indicano se è possibile che una variabile o un'espressione abbiano un valore negativo.
    2016-12-31 06: 46: 02Z
  3. Ho il seguente dubbio, ho posto la domanda, nessuna risposta soddisfacente ancora, date un'occhiata qui, stackoverflow.com/questions/41399092/...
    2016-12-31 08: 01: 55Z

Ha chiesto solo informazioni su firmato e non firmato. Non so perché la gente stia aggiungendo cose extra in questo. Lascia che ti dica la risposta.

  1. Unsigned: consiste solo di valori non negativi compresi tra 0 e 255.

  2. Firmato: consta di valori sia negativi che positivi ma in diversi formati come

    • da 0 a +127
    • -1 a -128

E questa spiegazione riguarda il sistema numerico a 8 bit.

    
56
2019-05-15 09: 24: 20Z

Solo pochi punti per completezza:

  • questa risposta sta discutendo solo le rappresentazioni dei numeri interi. Potrebbero esserci altre risposte per virgola mobile;

  • la rappresentazione di un numero negativo può variare. Il più comune (di gran lunga - è quasi universale oggi) in uso oggi è two's complement . Altre rappresentazioni includono il proprio complemento (abbastanza raro) e magnitudine firmata ​​strong> (incredibilmente raro - probabilmente usato solo su pezzi da museo) che sta semplicemente usando il bit più alto come indicatore di segno con il restano bit che rappresentano il valore assoluto del numero.

  • Quando si utilizza il complemento a due, la variabile può rappresentare un intervallo più ampio (di uno) di numeri negativi rispetto ai numeri positivi. Questo perché lo zero è incluso nei numeri 'positivi' (poiché il bit del segno non è impostato su zero), ma non i numeri negativi. Ciò significa che il valore assoluto del numero negativo più piccolo non può essere rappresentato.

  • quando si usa il complemento o la magnitudine firmata di uno si può avere zero come numero positivo o negativo (che è uno dei motivi per cui queste rappresentazioni sonoin genere non utilizzato).

15
2008-10-29 19: 11: 52Z
  1. Se scrivo unsigned int a = -2, e firmato int b = -2, la rappresentazione sottostante sarebbe la stessa, so che non va bene avere un numero senza segno dato un valore negativo, ma ancora se lo dò, quale sarà la rappresentazione sottostante?
    2016-12-30 06: 10: 23Z
  2. Minore pecca: il segno e la magnitudine sono usati nel virgola mobile IEEE, quindi è piuttosto comune. : -)
    2017-02-13 13: 36: 05Z

Secondo quanto appreso in classe, gli interi con segno possono rappresentare sia i numeri negativi che , mentre gli interi senza segno sono solo non negativi.

Ad esempio, guardando un numero 8-bit :

valori non firmati da 0 a 255

I valori

​​ firmati vanno da -128 a 127

    
13
2016-01-27 01: 28: 41Z

Tutto tranne il punto 2 è corretto. Ci sono molte notazioni diverse per i segni firmati, alcune implementazioni usano il primo, altri usano l'ultimo e altri ancora usano qualcosa di completamente diverso. Tutto dipende dalla piattaforma con cui stai lavorando.

    
11
2008-10-29 18: 31: 18Z
  1. È la cosa little-endian e big-endian?
    2008-10-29 18: 32: 46Z
  2. little vs. big endian ha a che fare con l'ordine dei byte sulla piattaforma. Little Endian potrebbe fare 0xFF 0xFE 0x7F mentre big endian farà 0x7F 0xFE 0xFF.
    2008-10-29 18: 35: 51Z

Un'altra differenza è quando si converte tra numeri interi di dimensioni diverse.

Ad esempio, se stai estraendo un numero intero da un flusso di byte (diciamo 16 bit per semplicità), con valori senza segno, puoi fare:

 
i = ((int) b[j]) << 8 | b[j+1]

(probabilmente dovrebbe lanciare il byte 2 nd , ma suppongo che il compilatore farà la cosa giusta)

Con i valori firmati dovresti preoccuparti dell'estensione del segno e fare:

 
i = (((int) b[i]) & 0xFF) << 8 | ((int) b[i+1]) & 0xFF
    
10
2014-07-18 09: 04: 09Z
  1. questo funziona perfettamente!
    2014-10-15 19: 15: 11Z

In generale è corretto. Senza sapere nulla di più sul perché stai cercando le differenze non riesco a pensare a nessun altro differenziatore tra firmato e non firmato.

    
4
2008-10-29 18: 30: 24Z

Al di sopra e al di sopra di ciò che altri hanno detto, in C, non è possibile sovrascrivere un intero senza segno; il comportamento è definito come modulo aritmetico. È possibile eseguire l'overflow di un intero con segno e, in teoria (sebbene non in pratica sugli attuali sistemi mainstream), l'overflow potrebbe causare un errore (forse simile a un errore di divisione per zero).

4
2008-10-29 18: 43: 52Z
  1. Si noti che l'overflow di interi con segno fa scattare un comportamento indefinito, ei moderni compilatori sono ultra-aggressivi su come individuare questo e sfruttarlo per modificare il programma in modi inaspettati ma tecnicamente legittimi perché E 'permesso assumere comportamenti non definiti che non si verifichino - grosso modo. Questo è molto più un problema ora di quanto non fosse 7 anni fa.
    2015-10-24 18: 42: 48Z
  1. Sì, il numero intero senza segno può memorizzare un valore elevato.
  2. No, ci sono diversi modi per mostrare valori positivi e negativi.
  3. Sì, il numero intero con segno può contenere valori sia positivi sia negativi.
4
2013-04-25 09: 45: 26Z

(in risposta alla seconda domanda) Usando solo un bit di segno (e non il complemento a 2), si può finire con -0. Non molto carina.

    
4
2013-12-20 16: 09: 59Z
  1. Solo per aggiungere a questa risposta, in pratica significa che 10 == 00 dove entrambi i numeri sono base 2.
    2013-04-10 11: 21: 32Z

Gli interi senza segno sono molto più propensi a catturarti in una trappola particolare rispetto agli interi con segno. La trappola viene dal fatto che mentre 1 & 3 sopra sono corretti, entrambi i tipi di numeri interi possono essere assegnati un valore al di fuori dei limiti di ciò che può "contenere" e verrà convertito automaticamente.

 
unsigned int ui = -1;
signed int si = -1;

if (ui < 0) {
    printf("unsigned < 0\n");
}
if (si < 0) {
    printf("signed < 0\n");
}
if (ui == si) {
    printf("%d == %d\n", ui, si);
    printf("%ud == %ud\n", ui, si);
}

Quando lo esegui, otterrai il seguente risultato anche se entrambi i valori sono stati assegnati a -1 e sono stati dichiarati in modo diverso.

 
signed < 0
-1 == -1
4294967295d == 4294967295d
    
3
2011-02-04 21: 35: 53Z

I numeri interi firmati in C rappresentano numeri. Se a e b sono variabili di tipi interi con segno, lo standard non richiederà mai che un compilatore faccia in modo che l'espressione a+=b memorizzi in a qualcosa di diverso dalla somma aritmetica dei rispettivi valori. A dire il vero, se la somma aritmetica non rientrasse nel a, il processore potrebbe non essere in grado di inserirlo, ma lo standard non richiederebbe al compilatore di troncare o avvolgere il valore, o fare qualcosa per altro se i valori che superano i limiti per i loro tipi. Nota che mentre lo standard non lo richiede, le implementazioni C sono in grado di intercettare gli overflow aritmetici con i valori firmati.

Gli interi non firmati in C si comportano come anelli algebrici astratti di interi che sono congruenti modulo un po 'potere di due, tranne in scenari che comportano conversioni a, o operazioni con, tipi più grandi. Convertire un numero intero di qualsiasi dimensione in un tipo senza segno a 32 bit produrrà il membro corrispondente alle cose che sono congruenti a quel numero intero di 4.294.967.296. La ragione per cui sottrarre 3 da 2 produce 4.294.967.295 è che l'aggiunta di qualcosa di congruente a 3 a qualcosa di congruente a 4.294.967.295 produrrà qualcosa di congruente a 2.

I tipi di anelli algebrici astratti sono spesso cose utili da avere; sfortunatamente, C usa la firma come fattore decisivo per stabilire se un tipo debba comportarsi come un anello. Peggio ancora, i valori senza segno vengono considerati come numeri anziché come membri dell'anello quando vengono convertiti in tipi più grandi, e i valori senza segno inferiore a int vengono convertiti in numeri quando viene eseguita qualsiasi aritmetica su di essi. Se v è un uint32_t che equivale a 4,294,967,294, allora v*=v; dovrebbe fare v=4. Sfortunatamente, se int è a 64 bit, allora non si può dire cosa potrebbe fare v*=v;.

Dato lo standard così com'è, io wsuggerirei di usare i tipi senza segno nelle situazioni in cui si desidera il comportamento associato agli anelli algebrici e i tipi firmati quando si vuole rappresentare i numeri. È sfortunato che C abbia fatto le distinzioni come ha fatto, ma sono quello che sono.

    
3
2014-04-25 22: 33: 55Z

L'unica differenza garantita ​​em> tra un valore firmato e un valore non firmato in C è che il valore firmato può essere negativo, 0 o positivo, mentre un non firmato può essere solo 0 o positivo. Il problema è che C non definisce il formato dei tipi (quindi non sapere che i tuoi numeri interi siano in complemento a due). A rigor di termini i primi due punti che hai citato non sono corretti.

    
0
2010-07-12 01: 58: 38Z

È necessario utilizzare numeri interi non firmati durante la programmazione su sistemi embedded. Nei loop, quando non è necessario inserire interi con segno, l'uso di numeri interi senza segno salverà la sicurezza necessaria per progettare tali sistemi.

    
0
2014-01-14 19: 47: 49Z
fonte posta Qui