2016-05-04 14 views
1

Hier ist der Code-Schnipsel:Javascript verschieben rechts eine negative Zahl

var i = 101; 
console.log('101: ' + i.toString(2)); 
console.log('101 >> 1: ' + (i >> 1).toString(2)); 

var l = -101; 
console.log('-101: ' + l.toString(2)); 
console.log('-101 >> 1: ' + (l >> 1).toString(2));' 

Ausgang:

"101: 1100101" 
"101 >> 1: 110010" 
"-101: -1100101" 
"-101 >> 1: -110011" 

Warum -101 >> 1 ist -110011 statt -110010?


Update: das Buch Professional JavaScript für Web-Entwickler erklärt, wie js speichert eine negative Zahl:

  1. die binäre Darstellung des absoluten Werts der negativen Zahl erhalten
  2. 0s ersetzen 1s und 1s mit 0s
  3. add 1 zu dem Ergebnis von Schritt 2
erste -101 in seine binären Darstellung konvertieren

Also in meinem Fall -101 >> 1 wir:

  1. Die binäre Darstellung von Math.abs (-101) ist:

  2. invertieren die 0 und 1:

  3. 1 hinzufügen, bis zum Ende:

  4. Nun verschieben Sie sich nach rechts von 1:

Die obige Binärdatei sollte das korrekte Ergebnis von -101 >> 1 sein, aber beim Protokollieren der Binärdarstellung einer negativen Zahl setzt Javascript einfach ein negatives Vorzeichen vor die binäre Darstellung der positiven Zahl:

var x = 15; 
console.log(x.toString(2)); // output: 1111 

var y = -15; 
console.log(y.toString(2)); // output: -1111 

Für unser Beispiel bedeutet dies, dass, wenn das Ergebnis der -101 >> 1, JS Anmeldung ausgibt minus sign + the binary representation of the positive number.Aber die positive Zahl ist nicht 101 >> 1 weil 101 >> 1 gibt Ihnen:

(101 >> 1).toString(2); // output: 110010 
(-101 >> 1).toString(2); // output: -110011, not -110010! 

das richtige Ergebnis zu erhalten, haben wir den oben genannten Schritt umkehren 1-3:

1111 1111 1111 1111 1111 1111 1100 1101 // this is the result we get from step 4 

Umkehr Schritt 3 von 1 subtrahiert, erhalten wir:

1111 1111 1111 1111 1111 1111 1100 1100 

Umkehr Schritt 2 durch invertieren 0 und 1:

0000 0000 0000 0000 0000 0000 0011 0011 

Umkehrschritt 1 durch diese binäre Umwandlung Integer:

parseInt(110011, 2); // output: 51 

Wenn schließlich JS das Ergebnis -101 >> 1 anmeldet, wird es minus sign + the binary representation of 51 wird, das:

(51).toString(2);  // output: 110011 
(-101 >> 1).toString(2); // output: -110011 
+0

'>>' (Rechtsverschobenes Vorzeichen) - ** Dieser Operator verschiebt den ersten Operanden um die angegebene Anzahl von Bits nach rechts. Überschüssige Bits, die nach rechts verschoben sind, werden verworfen. Kopien des linken Bits werden von links nach innen geschoben. Da das neue Bit ganz links den gleichen Wert wie das vorhergehende Bit ganz links hat, ändert sich das Vorzeichenbit (das Bit ganz links) nicht. Daher der Name "sign-propagating". ** – evolutionxbox

Antwort

0

dass negative Erinnern Zahlen werden als 2s-Komplement gespeichert. Der Einfachheit halber wollen wir sagen, es ist ein 1-Byte-Ganzzahl mit Vorzeichen, dann würde -101 als

1 0000 0000 (256) 
- 0110 0101 (101) 
= 1001 1011 (155 if it were unsigned, -101 in signed) 
gespeichert werden

Wenn Bitverschiebung eine negative Zahl, Sie mit der rechten Pad mit 1 s statt 0 s (sonst Sie‘ d das Vorzeichenbit verlieren), so das Ergebnis ist:

1001 1011 
     >> 1 
= 1100 1101 

Das ist 205, wenn es eine vorzeichenlose Ganzzahl wäre. Dann 2s-Ergänzung es zurück zu lösen 256 - x = 205 =>x = 51

Ta-da? : D

+0

Dies ist unvollständig. Sie müssen erklären, dass "i" eigentlich ein float ist, aber die Operanden von '>>' in vorzeichenbehaftete 32-Bit-Ints konvertiert werden, und das Ergebnis wird zurück in einen Gleitkommawert konvertiert. – EML

+0

Ich habe ein Buch gelesen und die Frage aktualisiert. Glaubst du, meine Erklärung ist richtig? – Cheng

Verwandte Themen