2010-05-03 15 views
15

Czytałem w wielu miejscach, że przepełnienie liczby całkowitej jest dobrze zdefiniowane w C, w przeciwieństwie do podpisanego odpowiednika.Pytanie dotyczące zachowania C dla niepodpisanego liczby całkowitej underflow

Czy to niedomiar jest taki sam?

Na przykład:

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

Dzięki.

Nie mogę sobie przypomnieć gdzie, ale czytałem gdzieś, że arytmetyczna na niepodpisanych typach całek jest modularna, więc jeśli tak było, to -1 == Mod UINT_MAX (UINT_MAX + 1).

+2

Uważam, że termin "niedopełnienie" odnosi się tylko do liczb zmiennoprzecinkowych, gdzie nie można przedstawić liczb bardzo bliskich zeru. Liczby całkowite nie miałyby tego problemu. – WildCrustacean

+0

@bde Zgadzam się, że jest to technicznie poprawne stwierdzenie, ale termin jest często przeciążany z powodu naruszenia warunku brzegowego w dolnym końcu systemu liczbowego. – vicatcu

Odpowiedz

22

§6.2.5 ustęp 9:

obliczeniach obejmujących unsigned parametrami może nie nadmiar, ponieważ wynik, który nie może być reprezentowane przez otrzymany unsigned całkowita jest zmniejszona modulo liczba, która jest jedną o większą niż najwyższa wartość, która jest może być reprezentowana przez wynikowy typ .

Edit:

Niestety, źle odniesienia, ale wynik jest nadal przypięte dół. Prawidłowe odniesienia §6.3.1.3 (podpisane i konwersja całkowita bez znaku)

jeżeli nowy typ jest unsigned wartość jest przekształcany przez wielokrotnie dodanie lub odjęcie jeden więcej niż wartość maksymalna, która może być reprezentowany w nowym typie, aż do wartość znajduje się w zakresie nowego typu .

Tak, tak, x == UINT_MAX.

+0

Twoje odwołanie jest w porządku, ale nie dotyczy, ponieważ wyrażenie -1 zawiera podpisane operandy, niepodpisane operandy. –

+0

Pytanie już przyznaje, że przepełnienie jest dobrze zdefiniowane. Pytanie dotyczy liczb ujemnych, a nie pozytywnych. –

+0

@Doug, @Mark: Pytanie dotyczy konwersji z podpisanych na liczby całkowite bez znaku, określone w §6.3.1.3. –

4

-1, gdy wyrażone jako liczba 2 w dopełnieniu, wynosi 0xFF ... F, ile razy liczba bitów jest liczbą. W niepodpisanej liczbie spacji ta wartość jest maksymalną możliwą wartością (tj. Ustawione są wszystkie bity). Dlatego tak, x == UINT_MAX. Poniższy kod emituje "1" w ścisłym kompilatorze 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

Czy wymagane są dwa dodatkowe numery w standardzie? –

+4

Nie, dopełnienie 2s nie jest wymagane przez standard, więc to rozwiązanie nie jest ogólne; zobacz moją odpowiedź. –

+1

Nie jest wymagane, aby maksymalna wartość 'uint32_t' wynosiła' UINT_MAX' - "UINT_MAX" może być tak mała jak 65535 i tak duża, jak "ULONG_MAX". Jeśli zmienisz 'uint32_t' na' unsigned', będzie to poprawne. – caf

-1

Mieszacie podpisane i niepodpisane liczby, co jest nieefektywne.

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

To może, ale nie musi być nieco, ale jest doskonale zdefiniowane jako zgodne ze standardem C. –

+0

@ Stephen Canon, Untrue. Bitowa reprezentacja -1 nie jest zdefiniowana. Może to być na przykład uzupełnienie. –

+0

@Stepen, "standardowy-conformant" może, ale "dobrze zdefiniowany"? To jest sedno problemu. –

Powiązane problemy