445 Stimmen

Ganze Zahlen mit und ohne Vorzeichen

Liege ich richtig, wenn ich sage, dass der Unterschied zwischen einer Ganzzahl mit und ohne Vorzeichen ist?

  1. Unsigned kann einen größeren positiven Wert und keinen negativen Wert enthalten.
  2. Bei der vorzeichenlosen Version wird das führende Bit als Teil des Wertes verwendet, während bei der vorzeichenbehafteten Version das äußerste linke Bit verwendet wird, um festzustellen, ob die Zahl positiv oder negativ ist.
  3. Ganze Zahlen mit Vorzeichen können sowohl positive als auch negative Zahlen enthalten.

Gibt es weitere Unterschiede?

11voto

Jasper Bekkers Punkte 6545

Alles außer Punkt 2 ist richtig. Es gibt viele verschiedene Notationen für vorzeichenbehaftete Ints, einige Implementierungen verwenden die erste, andere die letzte und wieder andere verwenden etwas völlig anderes. Das hängt alles von der Plattform ab, mit der Sie arbeiten.

10voto

Mike Gleen Punkte 423

Ein weiterer Unterschied besteht in der Konvertierung zwischen ganzen Zahlen unterschiedlicher Größe.

Wenn Sie zum Beispiel eine ganze Zahl aus einem Byte-Stream (der Einfachheit halber sagen wir 16 Bit) mit vorzeichenlosen Werten extrahieren, könnten Sie das tun:

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

(sollte wahrscheinlich die 2 und Byte, aber ich nehme an, der Compiler wird das Richtige tun)

Bei vorzeichenbehafteten Werten müssten Sie sich um die Vorzeichenerweiterung kümmern und tun:

i = (((int) b[i]) & 0xFF) << 8 | ((int) b[i+1]) & 0xFF

7voto

Jonathan Leffler Punkte 694013

Abgesehen von dem, was andere gesagt haben, kann man in C eine ganze Zahl ohne Vorzeichen nicht überlaufen lassen; das Verhalten ist als Modulus-Arithmetik definiert. Man kann eine vorzeichenbehaftete Ganzzahl überlaufen lassen, und theoretisch (wenn auch nicht in der Praxis auf aktuellen Mainstream-Systemen) könnte der Überlauf einen Fehler auslösen (vielleicht ähnlich wie ein Divide by Zero-Fehler).

6voto

toddk Punkte 841

Im Allgemeinen ist das richtig. Ohne mehr darüber zu wissen, warum Sie nach den Unterschieden suchen, fallen mir keine weiteren Unterscheidungsmerkmale zwischen vorzeichenbehaftet und vorzeichenlos ein.

6voto

supercat Punkte 72939

Ganzzahlen mit Vorzeichen stehen in C für Zahlen. Wenn a y b Variablen vom Typ ganze Zahl mit Vorzeichen sind, wird der Standard niemals verlangen, dass ein Compiler den Ausdruck a+=b einlagern a etwas anderes als die arithmetische Summe ihrer jeweiligen Werte. Natürlich, wenn die arithmetische Summe nicht in die a der Prozessor könnte aber der Standard würde den Compiler nicht dazu verpflichten, den Wert abzuschneiden oder einzuschließen oder irgendetwas anderes zu tun, wenn die Werte die Grenzen für ihre Typen überschreiten. Beachten Sie, dass C-Implementierungen arithmetische Überläufe mit vorzeichenbehafteten Werten abfangen dürfen, obwohl der Standard dies nicht vorschreibt.

Ganze Zahlen ohne Vorzeichen verhalten sich in C wie abstrakte algebraische Ringe ganzer Zahlen, die modulo einer Zweierpotenz kongruent sind, außer in Szenarien, die Konvertierungen in oder Operationen mit größeren Typen beinhalten. Die Konvertierung einer ganzen Zahl von cualquier Größe zu einem 32-Bit-Typ ohne Vorzeichen ergibt das Element, das den Dingen entspricht, die kongruent zu dieser Ganzzahl mod 4.294.967.296 sind. Der Grund, warum die Subtraktion von 3 von 2 4.294.967.295 ergibt, ist, dass die Addition von etwas, das kongruent zu 3 ist, zu etwas, das kongruent zu 4.294.967.295 ist, etwas ergibt, das kongruent zu 2 ist.

Abstrakte algebraische Ringtypen sind oft eine praktische Sache; leider verwendet C die Vorzeichentreue als entscheidenden Faktor dafür, ob sich ein Typ wie ein Ring verhalten sollte. Schlimmer noch, vorzeichenlose Werte werden bei der Konvertierung in größere Typen eher als Zahlen denn als Ringglieder behandelt, und vorzeichenlose Werte kleiner als int werden in Zahlen umgewandelt, wenn mit ihnen arithmetisch gearbeitet wird. Wenn v est un uint32_t was gleichbedeutend ist mit 4,294,967,294 entonces v*=v; sollte machen v=4 . Leider, wenn int 64 Bit ist, dann kann man nicht sagen, was v*=v; tun könnte.

In Anbetracht des aktuellen Standards würde ich vorschlagen, vorzeichenlose Typen in Situationen zu verwenden, in denen man das mit algebraischen Ringen verbundene Verhalten wünscht, und vorzeichenbehaftete Typen, wenn man Zahlen darstellen möchte. Es ist bedauerlich, dass C die Unterscheidungen so getroffen hat, aber sie sind, wie sie sind.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X