2009-03-17 18 views
0

In einem TC++ - Compiler ist die Binärdarstellung (00000000000000101). Ich weiß, dass negative Zahlen als Zweierkomplement gespeichert werden, also -5 binär ist (111111111111011). Das höchstwertige Bit (Vorzeichenbit) ist 1, was anzeigt, dass es eine negative Zahl ist.Zweierkomplement-Binärform

Woher weiß der Compiler, dass es -5 ist? Wenn wir den oben angegebenen Binärwert (111111111111011) als vorzeichenlose Zahl interpretieren, wird es ganz anders aussehen?

Auch, warum ist die 1 Kompliment von -6 (1111111111111010)?

Antwort

8

Der Compiler weiß nicht. Wenn Sie -5 zu unsigned int abgeben, erhalten Sie 32763.

+0

Ja, der Cast sagt dem Compiler, wie man Bits an einem bestimmten Speicherort interpretiert. Im Allgemeinen hat es seine eigene Vorstellung davon, was wo wo wohnt, aber eine Besetzung wirft einen Schraubenschlüssel in Dinge. – Dan

+0

Nun, Sie müssen nicht einmal explizite Besetzung machen. – vartec

+0

ja der Compiler macht nur die Mathematik. Wenn Sie von -5 bis unsigned int übergeben, ist das Ergebnis immer UINT_MAX + 1-5, unabhängig davon, ob Vorzeichen-Betrag/Zwei-Komplement/Eins-Komplement irrelevant ist. –

2

ist das erste Bit gesetzt nur für negative Zahlen

Detaillierte Informationen here

+0

Aber für unsigned int kann das erste Bit gesetzt werden und es ist immer noch positive Zahl. – klew

0

Es ist genau das signifikanteste Bit zur Verfügung (es das Vorzeichenbit genannt) ist - wenn Sie eine Nummer signiert kennen, dann Wenn das MSB = 1 ist, weiß der Compiler (und die Laufzeit!), es als negativ zu interpretieren. Deshalb haben c-ähnliche Sprachen sowohl ganze Zahlen (positive und negative) als auch vorzeichenlose ganze Zahlen - in diesem Fall interpretierst du sie alle als positiv. Daher geht ein vorzeichenbehaftetes Byte von -128 bis 127, aber ein vorzeichenloses Byte von 0 bis 255.

+0

Tatsächlich geht ein vorzeichenbehaftetes Byte von -128 bis 127. – RobH

1

Wenn die Zahl als vorzeichenbehafteter Datentyp deklariert wird (und nicht in einen vorzeichenlosen Typ umgewandelt wird), weiß der Compiler, dass das negative Vorzeichen 1 ist. Warum also das 2er-Komplement anstelle des 1er-Komplements verwendet wird, möchten Sie nicht einen Wert von -0 haben, was das 1er-Komplement Ihnen erlauben würde, also haben sie das Zweierkomplement erfunden, um das zu beheben.

+0

Ich glaube, der wahre Grund war, Maschinensprache add/subtrahieren Algorithmen zu erlauben, das Zeichen der oeprants zu ignorieren und einfach eine bitweise Addition oder Subtraktion zu tun, Bit bei Bedarf zu tragen ... –

5

Der Compiler weiß, weil dies die Konvention ist, die die CPU nativ verwendet. Ihr Computer verfügt über eine CPU, die negative Zahlen in der Zweierkomplement-Notation speichert, so dass der Compiler dem Beispiel folgt. Wenn Ihre CPU die Komplement-Notation unterstützt, würde der Compiler das verwenden (wie übrigens bei IEEE-Floats).

Der Wikipedia-Artikel zum Thema erklärt, wie two's complement Notation funktioniert.

+0

+1: Zitieren Sie einige nützliche Dokumente; +1: es ist Hardware; +1: Der Compiler "weiß" nichts über die Nummer - Sie haben ihn als signiert oder unsigniert deklariert - Sie müssen ihn dann konsistent mit der Deklaration verwenden. –

3

Der Prozessor implementiert vorzeichenbehaftete und vorzeichenlose Anweisungen, die auf der Binärzahldarstellung anders arbeiten. Der Compiler weiß, welche dieser Anweisungen basierend auf dem Typ der beteiligten Operanden zu emittieren ist (d. H. int vs. unsigned int).

Der Compiler muss nicht wissen, ob eine Zahl negativ ist oder nicht, er gibt einfach die korrekten Maschinen- oder Zwischensprachenanweisungen für die beteiligten Typen aus. Die Implementierung dieser Anweisungen durch den Prozessor oder die Laufzeit ist normalerweise nicht so wichtig, ob die Zahl negativ ist oder nicht, da die Formulierung der Zweierkomplement-Arithmetik so ist, dass sie für positive oder negative Zahlen gleich ist (in der Tat ist dies der Chef) Vorteil der Zweierkomplementarithmetik). Was würde müssen wissen, ob eine Zahl negativ ist, wäre so etwas wie printf(), und wie Andrew Jaffe wies darauf hin, das MSBit gesetzt wird, ist ein Hinweis auf eine negative Zahl im Zweierkomplement.

+0

Wenn ich vorzeichen int a = -1 schreibe, dann ist "-1" in Zweierkomplement Form 11111111 11111111 11111111 11111111 und dann, wenn ich% d zu interpretieren es druckt -1 und% u, druckt 4294967295 und wenn ich schreibe signed int a = 2, druckt 2, wenn ich% d benutze und auch wenn ich% u verwende. Wenn 2 wäre in Zweierkomplement wäre es 11111111 11111111 11111111 11111101, und dann wäre es eine sehr diff Antwort, was ich wirklich fragen möchte ist, wann kommt 2 Komplement passieren, ist es abhängig von - Zeichen oder es passiert für jede ganze Zahl wenn type ist int signiert, was hier nicht der Fall sein muss. –

2

Die kewl Komplement von zwei ist, dass die Maschinensprache hinzufügen und Anweisungen subtrahieren all das ignorieren können, und tun nur binäre Arithmetik und es funktioniert ...

dh -3 + 4

in Binary 2-Komplement ist

1111 1111 1111 1101 (-3) 
+ 0000 0000 0000 0100 (4) 
    ------------------- 
    0000 0000 0000 0001 (1) 
+0

Weißt du, ich habe diese Eigenschaft der Zweierkomplement komplett vergessen. Das ist wahrscheinlich ein weiterer guter Grund, warum es erfunden wurde. – RobH

+0

genau der Grund –

+1

Wenn ich 'signed int a = -1' schreibe, dann '-1' in der 2er-Komplement-Form ist' 11111111 11111111 11111111 11111111' und dann, wenn ich% d zu interpretieren es druckt -1 und% u , druckt '4294967295' und wenn ich signed int a = 2 schreibe, druckt es 2, wenn ich'% d' benutze und auch wenn ich '% u' verwende. Wenn 2 in Zweierkomplement wäre, wäre es "11111111 11111111 11111111 11111101", und dann wäre es eine sehr differente Antwort, was ich wirklich fragen möchte ist, wann das Zweierkomplement geschieht, hängt davon ab - oder es passiert für jeden Ganzzahl, wenn der Typ int signiert ist, was hier nicht der Fall sein muss. –

2

lassen Sie uns ein Beispiel geben: haben wir zwei Zahlen in zwei Bytes binär: A = 10010111 B = 00100110 (Beachten Sie, dass die Maschine das Konzept von signed oder unsigned in dieser Ebene nicht kennt)

jetzt, wenn Sie diese zwei "hinzufügen" sagen, was macht die Maschine? es fügt einfach:

R = 10111101 (und tragen Bit: 1)

jetzt, wir Compiler- Notwendigkeit zu interpretieren den Betrieb -wie. Wir haben zwei Möglichkeiten: Die Nummern können signiert oder nicht signiert sein.

1 unsigned case: in c sind die Zahlen vom Typ "unsigned char" und die Werte sind 151 und 38 und das Ergebnis ist 189. Dies ist trivial.

2 - unterzeichnet Fall: wir, der Compiler, interpretieren die Zahlen entsprechend ihrer MSB und die erste Zahl ist -105 und die zweite ist immer noch 38. so -105 + 38 = -67. Aber -67 ist 10111101. Aber das haben wir schon im Ergebnis (R)! Das Ergebnis ist das gleiche, der einzige Unterschied ist, wie der Compiler es interpretiert.

Die Schlussfolgerung ist, dass, egal wie wir die Zahlen betrachten, die Maschine die gleiche Operation auf die Zahlen macht. Aber der Compiler wird die Ergebnisse wiederum interpretieren.

Beachten Sie, dass es nicht die Maschine ist, die das Konzept der 2er Komplement kennt. Es fügt nur zwei Zahlen hinzu, ohne den Inhalt zu beachten. Der Compiler schaut dann auf das Vorzeichenbit und entscheidet.

Wenn es zur Subtraktion kommt, ist dieses Mal wieder die Operation einzigartig: nehmen Sie das Zweierkomplement der zweiten Zahl und addieren Sie die zwei.