2010-05-03 9 views
15

Ho letto in molti punti che l'overflow intero è ben definito in C a differenza della controparte firmata.Domanda sul comportamento C per underflow intero non firmato

L'underflow è uguale?

Ad esempio:

unsigned int x = -1; // Does x == UINT_MAX? 

Grazie.

Non riesco a ricordare dove, ma ho letto da qualche parte che l'aritmetica su tipi interi senza segno è modulare, quindi se fosse il caso allora -1 == UINT_MAX mod (UINT_MAX + 1).

+2

Credo che il termine "underflow" sia applicabile solo ai numeri in virgola mobile, dove non è possibile rappresentare numeri molto vicini allo zero. Gli integer non avrebbero questo problema. – WildCrustacean

+0

@bde Sono d'accordo che si tratti di un'affermazione tecnicamente accurata, ma il termine è spesso sovraccarico per la violazione della condizione al contorno nella parte inferiore di un sistema numerico. – vicatcu

risposta

22

§6.2.5, paragrafo 9:

Un calcolo coinvolge firmati operandi può mai troppopieno, perché un risultato che non può essere rappresentato da tipo intero senza segno risultante viene ridotta modulo il numero che è uno superiore al valore più grande che può essere rappresentato dal tipo risultante.

Edit:

Siamo spiacenti, riferimento sbagliato, ma il risultato è ancora inchiodato. Il riferimento corretto è §6.3.1.3 (firmata e conversione intero senza segno):

se il nuovo tipo è senza segno, il valore viene convertito da ripetutamente aggiungendo o sottraendo un superiore al valore massimo che può essere rappresentato nel nuovo tipo fino al il valore è compreso nell'intervallo del nuovo tipo .

Quindi sì, x == UINT_MAX.

+0

Il tuo riferimento va bene, ma non è applicabile poiché l'espressione -1 coinvolge operandi firmati, non operandi non firmati. –

+0

La domanda ammette già che l'overflow è ben definito. La domanda riguarda numeri negativi, non positivi. –

+0

@Doug, @Mark: la domanda riguarda le conversioni dagli interi firmati a interi non firmati, che è specificato da §6.3.1.3. –

4

-1, quando espresso come numero di complemento a 2, equivale a 0xFF ... F per quanti bit è il numero. In uno spazio numerato senza segno tale valore è il valore massimo possibile (cioè tutti i bit sono impostati). Quindi sì, x == UINT_MAX. Il seguente codice emette "1" su una rigorosa compilatore C99:

#include <stdio.h> 
#include <stdint.h> 
#include <limits.h> 

int main(int argc, char **argv){ 
    uint32_t x = -1;  
    printf("%d", x == UINT_MAX ? 1 : 0); 
    return 0; 
} 
+1

I numeri del complemento a due sono richiesti dallo standard? –

+4

No, il complemento 2s non è richiesto dallo standard, quindi questa soluzione non è generale; guarda la mia risposta –

+1

Non è necessario che il valore massimo di 'uint32_t' sia' UINT_MAX' - 'UINT_MAX' può essere piccolo come 65535 e grande come' ULONG_MAX'. Se cambi 'uint32_t' a' unsigned' sarà corretto. – caf

-1

si stia mescolando firmati e numeri senza segno, che è uncool.

unsigned int x = 0u - 1u; // is OK though 
+3

Può essere o meno uncool, ma è perfettamente definito come conforme allo standard C. –

+0

@Stephen Canon, Untrue. La rappresentazione bit a bit di -1 non è definita. Potrebbe essere un complemento, per esempio. –

+0

@Stepen, "standard-conformant" forse, ma "ben definito"? Questo è il punto cruciale della domanda. –