Was ist der Unterschied zwischen unsigned int und signed int in C?

Lesezeit: 8 Minuten

Benutzeravatar von Anand Kumar
Anand Kumar

Betrachten Sie diese Definitionen:

int x=5;
int y=-5;
unsigned int z=5;

Wie werden sie im Gedächtnis gespeichert? Kann jemand die Bitdarstellung dieser im Speicher erklären?

dürfen int x=5 und int y=-5 dieselbe Bitdarstellung im Speicher haben?

  • Beste Erklärung Verknüpfung

    – Dhiren Hamal

    27. April um 18:12 Uhr

Benutzeravatar von paxdiablo
paxdiablo

ISO C gibt an, wo die Unterschiede liegen.

Das int Der Datentyp ist signiert und hat einen Mindestbereich von mindestens -32767 bis einschließlich 32767. Die tatsächlichen Werte sind in angegeben limits.h wie INT_MIN und INT_MAX beziehungsweise.

Ein unsigned int hat einen minimalen Bereich von 0 bis einschließlich 65535, wobei der tatsächliche Maximalwert ist UINT_MAX aus derselben Header-Datei.

Darüber hinaus schreibt der Standard keine Zweierkomplementnotation zur Kodierung der Werte vor, das ist nur eine der Möglichkeiten. Die drei zulässigen Typen hätten folgende Codierungen für 5 und -5 (unter Verwendung von 16-Bit-Datentypen):

        two's complement  |  ones' complement   |   sign/magnitude
    +---------------------+---------------------+---------------------+
 5  | 0000 0000 0000 0101 | 0000 0000 0000 0101 | 0000 0000 0000 0101 |
-5  | 1111 1111 1111 1011 | 1111 1111 1111 1010 | 1000 0000 0000 0101 |
    +---------------------+---------------------+---------------------+
  • Im Zweierkomplement erhalten Sie eine negative Zahl, indem Sie alle Bits invertieren und dann 1 addieren.
  • Im Einerkomplement erhält man ein Negativ einer Zahl, indem man alle Bits invertiert.
  • In Vorzeichen/Größe ist das obere Bit das Vorzeichen, also invertieren Sie es einfach, um das Negative zu erhalten.

Beachten Sie, dass positive Werte für alle Darstellungen dieselbe Codierung haben, nur die negativen Werte sind unterschiedlich.

Beachten Sie außerdem, dass Sie für vorzeichenlose Werte keines der Bits für ein Vorzeichen verwenden müssen. Das bedeutet, dass Sie auf der positiven Seite mehr Reichweite erhalten (natürlich auf Kosten von keinen negativen Codierungen).

Und nein, 5 und -5 kann nicht die gleiche Codierung haben, unabhängig davon, welche Darstellung Sie verwenden. Sonst wäre es nicht möglich, den Unterschied zu erkennen.


Abgesehen davon gibt es derzeit sowohl im C- als auch im C++-Standard Bestrebungen, das Zweierkomplement als einzige Codierung für negative Ganzzahlen zu benennen.

  • Es erfordert jedoch die Wahl zwischen Zweierkomplement, Einerkomplement oder Vorzeichengröße.

    – Café

    28. September 2010 um 11:25 Uhr

  • Könnte eine konforme Implementierung die gleiche Darstellung für vorzeichenbehaftete und vorzeichenlose Zahlen verwenden und lediglich das Vorzeichenbit erzwingen, dass es für Operationen auf Typen, die als „vorzeichenlos“ deklariert sind, „0“ ist (so dass es im Wesentlichen ein „Auffüllbit“ wäre)?

    – Superkatze

    28. September 2010 um 22:56 Uhr

  • Möglicherweise, denke ich, ist das zulässig, aber da der Mindestbereich 0-65536 beträgt, benötigen Sie für dieses Schema mindestens 17 Bit. Das würde 16-Bit-Ganzzahlen ohne Vorzeichen auszählen, aber wahrscheinlich mit 32-Bit-Ganzzahlen in Ordnung sein. Ich bin mir dessen nicht sicher, da ich nicht genau untersucht habe, ob das Umhüllen von unsignierten Daten von ISO spezifiziert wird, aber es scheint zumindest für die aktuelle CPU-Generation ineffizient / verschwenderisch zu sein.

    – paxdiablo

    29. September 2010 um 0:01 Uhr

  • Das Zweierkomplement ist ein sehr elegantes System. Es ist nicht nur einfach in Hardware zu implementieren, sondern ermöglicht Ihnen auch, die vorhandene Additionshardware zur Durchführung von Subtraktionen zu verwenden – die Addition einer Zweierkomplementzahl zu einer vorzeichenlosen Ganzzahl führt eine Subtraktion durch.

    – Räumlich

    19. August 2013 um 16:50 Uhr

  • Hallo. Ich kannte bisher nur die Vorzeichen-/Größencodierung, und es wird im Artikel über Java angenommen javamex.com/java_equivalents/unsigned.shtml “es bewahrt das Zeichen” … also ist diese Drei-Varianten-Freiheit in anderen Sprachen als C verfügbar / verwendet?

    – Valter Ekholm

    16. Juli 2019 um 22:35 Uhr

Da es nur ums Gedächtnis geht, werden am Ende alle Zahlenwerte binär gespeichert.

Eine vorzeichenlose 32-Bit-Ganzzahl kann Werte von ausschließlich binären Nullen bis hin zu binären Einsen enthalten.

Wenn es um eine 32-Bit-Ganzzahl mit Vorzeichen geht, bedeutet dies, dass eines ihrer Bits (höchstwertig) ein Flag ist, das den Wert als positiv oder negativ markiert.

  • Können Sie mir in diesem Fall sagen, wie ich überprüfen kann, ob der Wert, der einem s8 ​​(8-Bit-Signatur) gegeben wird, außerhalb des Bereichs liegt oder nicht. Soll ich den Wert mit 0x7F anstelle von 0xFF vergleichen? Und sollte ich zuerst nach dem Vorzeichenbit suchen? Danke

    – Das Biest

    26. Mai 2017 um 2:01 Uhr

Benutzeravatar von Douglas Leeder
Douglas Leder

Das C-Standard gibt an, dass vorzeichenlose Zahlen binär gespeichert werden. (Mit optionalen Füllbits). Vorzeichenbehaftete Zahlen können in einem von drei Formaten gespeichert werden: Größe und Vorzeichen; Zweierkomplement oder Einerkomplement. Interessanterweise schließt das bestimmte andere Darstellungen wie aus Überschuss-n oder Basis −2.

Auf den meisten Rechnern und Compilern werden vorzeichenbehaftete Zahlen jedoch im Zweierkomplement gespeichert.

int ist normalerweise 16 oder 32 Bit. Das sagt die Norm int sollte das sein, was für den zugrunde liegenden Prozessor am effizientesten ist, solange dies der Fall ist >= short und <= long dann ist es von der Norm erlaubt.

Auf einigen Maschinen und Betriebssystemen hat die Geschichte Ursachen int jedoch nicht die beste Größe für die aktuelle Iteration der Hardware.

  • ok auf 16-Bit-Compiler können Sie mir sagen, wie int x = 5 und int y = -5 intern im Speicher gespeichert werden. Bitte geben Sie die Bitdarstellung an

    – Anand Kumar

    28. September 2010 um 11:18 Uhr

  • -1: Leider ist Ihre Antwort falsch. C schreibt sehr genau vor, wie ganze Zahlen darzustellen sind. Insbesondere für vorzeichenlose Typen gibt es nicht viel Auswahl für eine Compiler-Implementierung. Aber selbst für signierte Typen ist der Standard ziemlich restriktiv. Und int ist keineswegs der für den Prozessor effizienteste Typ. In den meisten Fällen wird heutzutage bei 32 Bit festgehalten (nur aus syntaktischen Gründen), wobei 64 oft am effizientesten ist.

    – Jens Gustedt

    28. September 2010 um 11:39 Uhr

  • @Jens Gustedt: “Leider”, die Antwort von Douglas ist sehr richtig. Der Standard unterscheidet nicht zwischen Zweierkomplement, Einerkomplement oder vorzeichenbehafteter Größe, er besagt lediglich, dass die positiven Darstellungen von vorzeichenbehafteten Ganzzahlen mit der Darstellung derselben Werte in vorzeichenlosen Ganzzahlen identisch sein müssen. Der Standard besagt auch, dass “ein ‘einfacher’ int Objekt hat die natürliche Größe, die von der Architektur der Ausführungsumgebung vorgeschlagen wird”. Dass Implementierungen dies vermasselt haben, ist nicht die Schuld der Sprache. Douglas hat absolut Recht, also gebe ich +1, um Ihre -1 auszugleichen.

    – DevSolar

    28. September 2010 um 12:16 Uhr


  • @DevSolar: Der Standard hat den Ausdruck, den Sie zitieren, ja, aber andererseits schränkt er viele von Ihnen ein, die ihn implementieren könnten, also ist das Ergebnis, wie ich es gesagt habe, denke ich. (Es gibt nur 5 Standard-Ganzzahltypen, und wenn Sie 8-, 16-, 32-, 64- und 128-Bit-Typen haben möchten, haben Sie keine andere Wahl int bei 32 Bit.) Und ich denke, dass Douglas’ Satz the C standard doesn't specify how integers are stored in memory kann so nicht stehen. Die Norm hat mehrere Seiten, um dies zu spezifizieren. ZB heißt es, dass es nur die drei von Ihnen erwähnten Zeichendarstellungen gibt und keine anderen.

    – Jens Gustedt

    28. September 2010 um 12:44 Uhr

  • Ok, ich habe tatsächlich eine Kopie des Standards gefunden, also werde ich meine Antwort korrigieren.

    – Douglas Leder

    28. September 2010 um 12:53 Uhr

Hier ist der sehr schöne Link, der die Speicherung von signiertem und unsigniertem INT in C erklärt –

http://answers.yahoo.com/question/index?qid=20090516032239AAzcX1O

Entnommen aus diesem obigen Artikel –

„Zweierkomplement genannter Prozess wird verwendet, um positive Zahlen in negative Zahlen umzuwandeln. Der Nebeneffekt davon ist, dass das höchstwertige Bit verwendet wird, um dem Computer mitzuteilen, ob die Zahl positiv oder negativ ist. Wenn das höchstwertige Bit eine 1 ist, dann die Zahl ist negativ. Wenn es 0 ist, ist die Zahl positiv.“

Unter der Annahme, dass int eine 16-Bit-Ganzzahl ist (was von der C-Implementierung abhängt, die meisten sind heutzutage 32-Bit), unterscheidet sich die Bit-Darstellung wie folgt:

 5 = 0000000000000101
-5 = 1111111111111011

Wenn binär 1111111111111011 auf ein unsigned int gesetzt würde, wäre es dezimal 65531.

  • ISO C tut es nicht Übrigens die Komplementdarstellung von Mandat 2.

    – paxdiablo

    28. September 2010 um 11:10 Uhr


  • ok auf 16-Bit-Compiler können Sie mir sagen, wie int x = 5 und int y = -5 intern im Speicher gespeichert werden. Bitte geben Sie die Bitdarstellung an

    – Anand Kumar

    28. September 2010 um 11:16 Uhr


  • @Anand: was willst du wirklich? da ist die Bitdarstellung (im Zweierkomplement) schon in der Antwort.

    – Jens Gustedt

    28. September 2010 um 11:40 Uhr

  • Hallo, ich frage, ob ich signed int x=5 schreibe; dann wird es den Wert in 2er-Komplementform speichern oder nicht und wenn ich signed int x= -5 schreibe; dann wird es den Wert im 2er-Komplement speichern oder nicht.

    – Anand Kumar

    28. September 2010 um 12:47 Uhr

  • ‘int x=5’ wird gleich gespeichert, egal ob 2er, 1er und sign/mag. In den meisten gängigen Implementierungen wird „int x=-5“ als Zweierkomplement gespeichert, aber verlassen Sie sich bei portablem Code nicht darauf.

    – Bill Evans bei Mariposa

    26. April 2011 um 15:34 Uhr

  • ISO C tut es nicht Übrigens die Komplementdarstellung von Mandat 2.

    – paxdiablo

    28. September 2010 um 11:10 Uhr


  • ok auf 16-Bit-Compiler können Sie mir sagen, wie int x = 5 und int y = -5 intern im Speicher gespeichert werden. Bitte geben Sie die Bitdarstellung an

    – Anand Kumar

    28. September 2010 um 11:16 Uhr


  • @Anand: was willst du wirklich? da ist die Bitdarstellung (im Zweierkomplement) schon in der Antwort.

    – Jens Gustedt

    28. September 2010 um 11:40 Uhr

  • Hallo, ich frage, ob ich signed int x=5 schreibe; dann wird es den Wert in 2er-Komplementform speichern oder nicht und wenn ich signed int x= -5 schreibe; dann wird es den Wert im 2er-Komplement speichern oder nicht.

    – Anand Kumar

    28. September 2010 um 12:47 Uhr

  • ‘int x=5’ wird gleich gespeichert, egal ob 2er, 1er und sign/mag. In den meisten gängigen Implementierungen wird „int x=-5“ als Zweierkomplement gespeichert, aber verlassen Sie sich bei portablem Code nicht darauf.

    – Bill Evans bei Mariposa

    26. April 2011 um 15:34 Uhr

1398840cookie-checkWas ist der Unterschied zwischen unsigned int und signed int in C?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy