2016-05-12 7 views
11

Hinweis: Alle folgenden Binärdarstellungen sollten von rechts nach links gelesen werden. Ich bin mir nicht sicher, warum ich so über sie nachdenke, aber ich wusste eigentlich nicht, dass Menschen auch von links nach rechts binär vertreten sind. Verwirrend!Warum ist ~ 5 === -6 in JavaScript?

In MDN Artikel für JavaScript bitweise Operatoren (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Bitwise_NOT) heißt es, dass der Operator ~ der bitweise Operator NOT ist. Auf Wikipedia (https://en.wikipedia.org/wiki/Bitwise_operation#NOT) heißt es: "Das bitweise NOT, oder Komplement, ist eine unäre Operation, die logische Negation für jedes Bit ausführt und das Einerkomplement des gegebenen binären Wertes bildet. Bits, die 0 sind, werden 1, und Diejenigen, die 1 sind, werden 0. "

Nun nehmen Sie die Nummer 5 in binär: 0101

Wenn ich ~5 in meinem Browser-Konsole eingeben, erhalte ich -6 deren binäre Darstellung 1110 ist. Ich erwartete, dass die Negation 0101 in 1010 umwandelt, was tatsächlich 10 ist (oder -2, wenn die Ziffer ganz links als Vorzeichen genommen wird).

Alle Erklärungen, die ich von JavaScript's ~ Operator gelesen habe, sagt, dass es die Zahl zu - (x + 1) auswertet, aber das erklärt mir logisch nicht, was dieser Operator auf einer "bitweisen" Ebene macht.

Grundsätzlich 0101 wird 1110.

Was sind die Zwischenschritte, um diese Transformation zu bezeugen? Ich sehe, wie das führende Bit umgedreht wird, wodurch sich das Vorzeichen ändert. Aber das ist alles, was ich sammeln kann.

+3

hier gehen http://stackoverflow.com/questions/31377474/why-does-bitwise-not-1-equal-2 –

+0

Es ist das gleiche in allen Computern, die ein 2-Komplement-System für negative Zahlen verwenden – Soren

+2

[~ x == = - (x + 1): -)] (http://stackoverflow.com/questions/34349350/what-does-xy-represent-in-javascript) .. – choz

Antwort

3

Es führt tatsächlich ein bitweises NOT, die negative Zahl ist two's complement. Also ist der Wert 1010-6.

Zweierkomplement funktioniert grundsätzlich, indem das ganz linke Bit eine negative Zahl angibt und als negativer Wert genommen wird. Alle anderen 1 Bits werden zu dieser Nummer hinzugefügt. Zum Beispiel:

1010 => (-8 +0 +2 +0) => -6 
1111 => (-8 +4 +2 +1) => -1 
2

Why does bitwise "not 1" equal -2? ist die gleiche Idee.
Cerebrus Antwort in dem obigen Link (BINARY R -> L):
Es gibt 2 ganze Zahlen zwischen 1 und -2: 0 und -1

1 binär ist 00000000000000000000000000000001
0 binär ist 00000000000000000000000000000000
-1 in binär 11111111111111111111111111111111
-2 binär 11111111111111111111111111111110
ist (Komplement "binär" ist 2'S, in dem Fall einer nicht bitweise ~)

+0

Das verstehe ich (denke ich). Für mich wäre eine 1 "001" und eine -2 wäre "110", also die 1 mit invertierten Bits. Aber durch einfaches Invertieren der Bits wird 5 nicht zu -6. – papiro

+0

Ich sehe jetzt meine Verwirrung! Das äußerste linke Bit dient nicht nur dazu, das Vorzeichen anzuzeigen, sondern zählt auch für etwas Negatives. So sah '110' für mich wie negativ-zwei-null aus, aber tatsächlich ist (-4) -2-0 was alles zusammen addiert ist -2! Knifflig, knifflig – papiro

2

Sie kamen zu der Lösung ganz in der Nähe zu erkennen, dass das erste Bit das Vorzeichen ist jedoch der Rest des Bits nicht verwendet ‚wie besehen‘. Beim Rechnen werden vorzeichenbehaftete Zahlen tatsächlich durch Zweierkomplemente dargestellt.

Es gibt detaillierte Artikel über das Konzept auf Wikipedia und verschiedene andere Websites, aber kurz gesagt, wenn das erste Bit 1 (eine negative Zahl angibt), bilden die restlichen Bits eine Zahl, die im Grunde zeigt, wie viel Sie zur Mindestanzahl hinzufügen (z. B.in einer 8-Bit-Ganzzahl wäre das Minimum -256, das ist 11111111, also wird die Umkehrung 5 (00000101) 11111010 oder 250, so können Sie die Dezimalzahl erhalten, indem Sie die 250 zu -256 hinzufügen und Sie erhalten die -6). Diese Erklärung ist eine Vereinfachung für Dezimalsysteme, aber um zu verstehen, wie das funktioniert, sollten Sie wirklich einen ganzen Artikel über Zweierkomplement lesen.

2

Sie werden durch das Vorzeichenbit verwirrt und wo es platziert wird ....

die Anzahl der Bits erweitern (um zum Beispiel eine sehr kurze int von 8 Bit) und sehen

00000110 6 

Bit Inversion ~

00000101 5 
11111010 ~5 (bitwise inversion of 5) 

Und das Herunterzählen von Null

00000000 0 
11111111 -1 
11111110 -2 
11111101 -3 
11111100 -4 
11111011 -5 
11111010 -6 

So

11111010 -6 

und

11111010 ~5 

ist das gleiche.

Dies gilt nicht nur für JavaScript, aber für alles, was auf einem Computer läuft, der auf 2 Komplementzahl Systemen basieren - nicht sicher, ob JavaScript jemals auf etwas anderes läuft :-)