2010-05-03 6 views
15

Ich habe an vielen Stellen gelesen, dass Integerüberlauf in C wohldefiniert ist, anders als das signierte Gegenstück.Frage über C-Verhalten für vorzeichenlosen Integer-Unterlauf

Ist der Unterlauf gleich?

Zum Beispiel:

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

Dank.

Ich kann mich nicht erinnern wo, aber ich habe irgendwo gelesen, dass Arithmetik auf vorzeichenlosen Integraltypen modular ist, wenn das der Fall wäre, dann -1 == UINT_MAX mod (UINT_MAX + 1).

+2

Ich glaube, dass der Begriff "Unterlauf" nur wirklich auf Gleitkommazahlen anwendbar ist, wo Sie einige Zahlen nicht sehr nahe bei Null darstellen können. Ganze Zahlen hätten dieses Problem nicht. – WildCrustacean

+0

@bde Ich stimme zu, dass es sich um eine technisch korrekte Aussage handelt, aber der Begriff ist oft wegen Verletzung der Randbedingung am unteren Ende eines Zahlensystems überladen. – vicatcu

Antwort

22

§6.2.5 Absatz 9:

eine Berechnung unsigned Operanden beteiligt nie Überlauf kann, weil ein Ergebnis, das durch Art die resultierende ganze Zahl ohne Vorzeichen dargestellt wird, kann nicht reduziert werden, ist modulo die Zahl, die eine größer als der größte Wert ist, der durch den resultierenden Typ dargestellt werden kann.

Edit:

Sorry, falsche Referenz, aber das Ergebnis fixiert ist nach wie vor nach unten. Die korrekte Referenz wird §6.3.1.3 (mit und ohne Vorzeichen integer conversion):

, wenn der neue Typ ist unsigned wird der Wert umgewandelt, indem wiederholt Addieren oder Subtrahieren einer mehr als der maximale Wert, der im neuen Typ dargestellt werden, bis der Wert im Bereich des neuen Typs liegt.

Also ja, x == UINT_MAX.

+0

Ihre Referenz ist in Ordnung, aber nicht anwendbar, da der Ausdruck -1 vorzeichenbehaftete Operanden enthält, nicht vorzeichenlose Operanden. –

+0

Die Frage gibt bereits zu, dass Überlauf gut definiert ist. Die Frage ist über negative Zahlen, nicht positiv. –

+0

@Doug, @Mark: Die Frage bezieht sich auf Konvertierungen von vorzeichenbehafteten in vorzeichenlose Ganzzahlen, die in § 6.3.1.3 spezifiziert sind. –

4

-1, wenn es als Zweierkomplementzahl ausgedrückt wird, beträgt 0xFF ... F für wie viele Bits auch immer Ihre Nummer ist. In einem vorzeichenlosen Zahlenraum ist dieser Wert der maximal mögliche Wert (d. H. Alle Bits sind gesetzt). Also ja, x == UINT_MAX. Der folgende Code gibt "1" auf einem strengen C99-Compiler aus:

#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

Werden Zweierkomplement-Nummern vom Standard benötigt? –

+4

Nein, das 2s-Komplement wird vom Standard nicht benötigt, daher ist diese Lösung nicht allgemein; Sieh meine Antwort. –

+1

Es ist nicht erforderlich, dass der maximale Wert von "uint32_t" "UINT_MAX" - "UINT_MAX" so klein wie 65535 und so groß wie "ULONG_MAX" ist. Wenn Sie dieses 'uint32_t' in' unsigned' ändern, ist es korrekt. – caf

-1

Sie mischen vorzeichenbehaftete und unsigned Nummern, die uncool ist.

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

Es kann oder kann nicht uncool sein, aber es ist perfekt definiert Standard-konform C. –

+0

@ Stephen Canon, Unwahr. Die bitweise Darstellung von -1 ist nicht definiert. Es könnte zum Beispiel eine Ergänzung sein. –

+0

@Stepen, "standardkonform" vielleicht, aber "gut definiert"? Das ist der Kern der Frage. –