Bin ich richtig zu sagen, dass der Unterschied zwischen einer vorzeichenbehafteten und einer vorzeichenlosen Ganzzahl ist:
- Unsigned kann einen größeren positiven Wert und keinen negativen Wert enthalten.
- Unsigned verwendet das führende Bit als Teil des Werts, während die signierte Version das Bit ganz links verwendet, um festzustellen, ob die Zahl positiv oder negativ ist.
- Ganzzahlen mit Vorzeichen können sowohl positive als auch negative Zahlen enthalten.
Irgendwelche anderen Unterschiede?
language-agnostic
integer
unsigned
signed
Shimmy Weitzhandler
quelle
quelle
Antworten:
Ja.
Es gibt verschiedene Möglichkeiten, vorzeichenbehaftete Ganzzahlen darzustellen. Am einfachsten zu visualisieren ist es, das Bit ganz links als Flag ( Vorzeichen und Größe ) zu verwenden. Häufiger ist jedoch das Zweierkomplement . Beide werden in den meisten modernen Mikroprozessoren verwendet - Gleitkomma verwendet Vorzeichen und Größe, während Ganzzahlarithmetik das Zweierkomplement verwendet.
Ja
quelle
Ich werde auf Hardwareebene auf x86 auf Unterschiede eingehen. Dies ist meistens irrelevant, es sei denn, Sie schreiben einen Compiler oder verwenden Assemblersprache. Aber es ist schön zu wissen.
Erstens unterstützt x86 native die komplementäre Darstellung signierter Zahlen durch die beiden . Sie können andere Darstellungen verwenden, dies würde jedoch mehr Anweisungen erfordern und im Allgemeinen eine Verschwendung von Prozessorzeit bedeuten.
Was meine ich mit "nativer Unterstützung"? Grundsätzlich meine ich, dass es eine Reihe von Anweisungen gibt, die Sie für vorzeichenlose Nummern verwenden, und eine andere Reihe, die Sie für vorzeichenbehaftete Nummern verwenden. Vorzeichenlose Nummern können in denselben Registern wie vorzeichenbehaftete Nummern gespeichert werden, und Sie können vorzeichenbehaftete und vorzeichenlose Anweisungen mischen, ohne den Prozessor zu beunruhigen. Es ist Sache des Compilers (oder Assembler-Programmierers), zu verfolgen, ob eine Nummer signiert ist oder nicht, und die entsprechenden Anweisungen zu verwenden.
Erstens haben Zweierkomplementzahlen die Eigenschaft, dass Addition und Subtraktion genauso sind wie bei vorzeichenlosen Zahlen. Es macht keinen Unterschied, ob die Zahlen positiv oder negativ sind. (Also mach einfach weiter und
ADD
undSUB
deine Zahlen ohne Sorge.)Die Unterschiede zeigen sich bei Vergleichen. x86 hat eine einfache Möglichkeit, sie zu unterscheiden: oben / unten zeigt einen vorzeichenlosen Vergleich an und größer / kleiner als ein vorzeichenbehafteter Vergleich. (ZB
JAE
bedeutet "Springen, wenn über oder gleich" und ist ohne Vorzeichen.)Es gibt auch zwei Sätze von Multiplikations- und Divisionsanweisungen, um mit vorzeichenbehafteten und vorzeichenlosen Ganzzahlen umzugehen.
Zuletzt: Wenn Sie beispielsweise nach einem Überlauf suchen möchten, würden Sie dies für signierte und nicht signierte Nummern unterschiedlich tun.
quelle
Er fragte nur nach unterschrieben und nicht unterschrieben. Ich weiß nicht, warum die Leute hier zusätzliche Dinge hinzufügen. Lass mich dir die Antwort sagen.
Ohne Vorzeichen: Es besteht nur aus nicht negativen Werten, dh 0 bis 255.
Signiert: Es besteht sowohl aus negativen als auch aus positiven Werten, jedoch in unterschiedlichen Formaten wie
Und diese Erklärung bezieht sich auf das 8-Bit-Zahlensystem.
quelle
Nur ein paar Punkte der Vollständigkeit halber:
In dieser Antwort werden nur ganzzahlige Darstellungen behandelt. Es kann andere Antworten für Gleitkomma geben;
Die Darstellung einer negativen Zahl kann variieren. Das heute am häufigsten verwendete (bei weitem fast universelle) ist das Zweierkomplement . Andere Darstellungen umfassen das eigene Komplement (ziemlich selten) und die vorzeichenbehaftete Größe (verschwindend selten - wahrscheinlich nur für Museumsstücke verwendet), wobei einfach das hohe Bit als Vorzeichenindikator verwendet wird, wobei die verbleibenden Bits den absoluten Wert der Zahl darstellen.
Bei Verwendung des Zweierkomplements kann die Variable einen größeren Bereich (um eins) negativer Zahlen als positive Zahlen darstellen. Dies liegt daran, dass Null in den 'positiven' Zahlen enthalten ist (da das Vorzeichenbit nicht für Null gesetzt ist), aber nicht in den negativen Zahlen. Dies bedeutet, dass der Absolutwert der kleinsten negativen Zahl nicht dargestellt werden kann.
Wenn Sie das eigene Komplement oder die vorzeichenbehaftete Größe verwenden, kann Null entweder als positive oder negative Zahl dargestellt werden (was einer der Gründe ist, warum diese Darstellungen normalerweise nicht verwendet werden).
quelle
Nach dem, was wir in der Klasse gelernt haben, können vorzeichenbehaftete Ganzzahlen sowohl positive als auch negative Zahlen darstellen, während vorzeichenlose Ganzzahlen nur nicht negativ sind.
Betrachten Sie beispielsweise eine 8-Bit- Zahl:
vorzeichenlose Werte
0
an255
signierte Werte reichen von
-128
zu127
quelle
Alles außer Punkt 2 ist korrekt. Es gibt viele verschiedene Notationen für signierte Ints, einige Implementierungen verwenden die erste, andere die letzte und wieder andere etwas völlig anderes. Das hängt alles von der Plattform ab, mit der Sie arbeiten.
quelle
Ein weiterer Unterschied besteht darin, dass Sie zwischen Ganzzahlen unterschiedlicher Größe konvertieren.
Wenn Sie beispielsweise eine Ganzzahl aus einem Bytestream (der Einfachheit halber 16 Bit) mit vorzeichenlosen Werten extrahieren, können Sie Folgendes tun:
(sollte wahrscheinlich das 2. Byte umwandeln , aber ich vermute, der Compiler wird das Richtige tun)
Bei signierten Werten müssten Sie sich um die Zeichenerweiterung kümmern und Folgendes tun:
quelle
Im Allgemeinen ist das richtig. Ohne mehr darüber zu wissen, warum Sie nach den Unterschieden suchen, kann ich mir keine anderen Unterscheidungsmerkmale zwischen signiert und nicht signiert vorstellen.
quelle
Über das hinaus, was andere gesagt haben, können Sie in C eine vorzeichenlose Ganzzahl nicht überlaufen lassen. Das Verhalten wird als Modularithmetik definiert. Sie können eine vorzeichenbehaftete Ganzzahl überlaufen lassen, und theoretisch (wenn auch nicht in der Praxis bei aktuellen Mainstream-Systemen) kann der Überlauf einen Fehler auslösen (möglicherweise ähnlich einem Fehler durch Teilen durch Null).
quelle
quelle
(als Antwort auf die zweite Frage) Wenn Sie nur ein Vorzeichenbit (und nicht das Zweierkomplement) verwenden, können Sie am Ende -0 erhalten. Nicht sehr hübsch.
quelle
Vorzeichenbehaftete Ganzzahlen in C stehen für Zahlen. Wenn
a
undb
Variablen von vorzeichenbehafteten Ganzzahltypen sind, verlangt der Standard niemals, dass ein Compiler den Ausdrucksspeichera+=b
ina
etwas anderes als die arithmetische Summe ihrer jeweiligen Werte umwandelt. Wenn die arithmetische Summe nicht passen würdea
, könnte der Prozessor sie möglicherweise nicht dort ablegen, aber der Standard würde nicht erfordern, dass der Compiler den Wert abschneidet oder umschließt oder irgendetwas anderes tut, wenn die Werte überschritten werden die Grenzen für ihre Typen. Beachten Sie, dass C-Implementierungen arithmetische Überläufe mit vorzeichenbehafteten Werten abfangen dürfen, obwohl der Standard dies nicht erfordert.Ganzzahlen ohne Vorzeichen in C verhalten sich wie abstrakte algebraische Ringe von Ganzzahlen, die kongruent modulo mit einer Zweierpotenz sind, außer in Szenarien, die Konvertierungen in oder Operationen mit größeren Typen beinhalten. Das Konvertieren einer Ganzzahl beliebiger Größe in einen 32-Bit-Typ ohne Vorzeichen ergibt das Element, das den Dingen entspricht, die mit dieser Ganzzahl mod 4,294,967,296 kongruent sind. Der Grund für das Subtrahieren von 3 von 2 ergibt 4.294.967.295, dass das Hinzufügen von etwas Kongruentem zu 3 zu etwas Kongruentem zu 4.294.967.295 etwas Kongruentes zu 2 ergibt.
Abstrakte algebraische Ringtypen sind oft praktisch; Leider verwendet C die Vorzeichen als entscheidenden Faktor dafür, ob sich ein Typ als Ring verhalten soll. Schlimmer noch, vorzeichenlose Werte werden bei der Konvertierung in größere Typen eher als Zahlen als als Ringelemente behandelt, und vorzeichenlose Werte, die kleiner sind als
int
die Umwandlung in Zahlen, wenn eine Arithmetik für sie ausgeführt wird. Wennv
auint32_t
gleich ist4,294,967,294
, dannv*=v;
sollte machenv=4
. Wennint
es sich um 64 Bit handelt, ist leider nicht abzusehen, wasv*=v;
dies tun könnte.In Anbetracht des Standards würde ich vorschlagen, vorzeichenlose Typen in Situationen zu verwenden, in denen das mit algebraischen Ringen verbundene Verhalten gewünscht wird, und vorzeichenbehaftete Typen, wenn Zahlen dargestellt werden sollen. Es ist bedauerlich, dass C die Unterscheidungen so getroffen hat, aber sie sind das, was sie sind.
quelle
Ganzzahlen ohne Vorzeichen fangen Sie mit größerer Wahrscheinlichkeit in einer bestimmten Falle als Ganzzahlen mit Vorzeichen. Die Falle kommt von der Tatsache, dass, obwohl 1 & 3 oben korrekt sind, beiden Arten von Ganzzahlen ein Wert zugewiesen werden kann, der außerhalb der Grenzen dessen liegt, was er "halten" kann, und dass er stillschweigend konvertiert wird.
Wenn Sie dies ausführen, erhalten Sie die folgende Ausgabe, obwohl beide Werte -1 zugewiesen und unterschiedlich deklariert wurden.
quelle
Der einzige garantierte Unterschied zwischen einem vorzeichenbehafteten und einem vorzeichenlosen Wert in C besteht darin, dass der vorzeichenbehaftete Wert negativ, 0 oder positiv sein kann, während ein vorzeichenloser Wert nur 0 oder positiv sein kann. Das Problem ist, dass C das Format der Typen nicht definiert (Sie wissen also nicht , dass Ihre Ganzzahlen in Zweierkomplementen vorliegen ). Genau genommen sind die ersten beiden Punkte, die Sie erwähnt haben, falsch.
quelle
Sie müssen vorzeichenlose Ganzzahlen verwenden, wenn Sie auf eingebetteten Systemen programmieren. Wenn in Schleifen keine vorzeichenbehafteten Ganzzahlen erforderlich sind, spart die Verwendung vorzeichenloser Ganzzahlen die Sicherheit, die für den Entwurf solcher Systeme erforderlich ist.
quelle