ECMAScript Bitwise Operators

Bitoperatoren werken op de laagste laag van het getal (dat wil zeggen de 32 cijfers die het getal representeren).

Herhaling van integer

ECMAScript heeft twee soorten integer, te weten signaalintegerr (die zowel positieve als negatieve getallen toestaat) en unsigned integerr (die alleen positieve getallen toestaat). In ECMAScript zijn alle integer-literaalwaarden standaard signaalintegerr, wat betekent dit?

Signaalintegerr gebruiken 31 cijfers om de waarde van het getal te representeren, het 32e cijfer wordt gebruikt om het teken van het getal te representeren, 0 voor een positief getal, 1 voor een negatief getal. Het bereik van de waarden varieert van -2147483648 tot 2147483647.

Er zijn twee verschillende manieren om getallen van het type signaalintegerr in binaire vorm op te slaan, een voor positieve getallen en een voor negatieve getallen. Positieve getallen worden opgeslagen in een ware binaire vorm, waarbij elk van de eerste 31 cijfers een macht van 2 vertegenwoordigt, beginnend met de 1e positie (bit 0) die 2 vertegenwoordigt0,de 2e positie (bit 1) staat voor 21Ongebruikte cijfers worden met 0 gevuld, wat betekent dat ze worden genegeerd. Bijvoorbeeld, de afbeelding hieronder toont de weergave van het getal 18.

32-bit geïndiceerde binair getal

De binaire versie van 18 gebruikt alleen de eerste 5 cijfers, die de geldige cijfers van dit getal zijn. Door het getal naar een binaire string te converteren, kun je de geldige cijfers zien:

var iNum = 18;
alert(iNum.toString(2));	//Uitvoer "10010"

Dit code geeft alleen "10010" uit, niet de 32-bitsweergave van 18. Andere cijfers zijn niet belangrijk, omdat alleen de eerste 5 cijfers nodig zijn om deze decimale waarde te bepalen. Zie de afbeelding hierboven:

5-bits geïndiceerde getal 18

Negatieve getallen worden ook opgeslagen als binaire codes, maar in de vorm van binaire complement. De stappen om de binaire complement van een getal te berekenen zijn in drie stappen:

  1. Bepaal de binaire weergave van de niet-negatieve versie van het getal (bijvoorbeeld, om de binaire complement van -18 te berekenen, moet je eerst de binaire weergave van 18 bepalen)
  2. Bepaal de binaire inversie, wat betekent dat je 0 moet vervangen door 1 en 1 door 0.
  3. Voeg 1 toe aan de binaire inversie

Om de binaire weergave van -18 te bepalen, moet je eerst de binaire weergave van 18 verkrijgen, zoals hieronder weergegeven:

0000 0000 0000 0000 0000 0000 0001 0010

Volgende, bereken de binaire inversie, zoals hieronder weergegeven:

1111 1111 1111 1111 1111 1111 1110 1101

Tot slot, voeg 1 toe aan de binaire inversie, zoals hieronder weergegeven:

1111 1111 1111 1111 1111 1111 1110 1101
                                      1
---------------------------------------
1111 1111 1111 1111 1111 1111 1110 1110

Dus, de binaire weergave van -18 is 1111 1111 1111 1111 1111 1111 1110 1110. Onthoud dat ontwikkelaars bij het behandelen van signed integers geen toegang hebben tot bit 31.

Het is interessant om te zien dat ECMAScript negatieve integers niet als binaire complement weergeeft, maar met een voorafgaand min-teken aan de standaard binaire code van de absolute waarde van het getal. Bijvoorbeeld:

var iNum = -18;
alert(iNum.toString(2)); // Uitvoer "-10010"

Dit stuk code geeft "-10010" uit, niet als binaire complement, om toegang tot bit 31 te vermijden. Voor het gemak gebruikt ECMAScript een eenvoudige manier om integers te behandelen, zodat ontwikkelaars zich geen zorgen hoeven te maken over hun gebruik.

Aan de andere kant behandelt een unsigned integer het laatste bit als een extra nummerpositie. In dit model wordt de 32e bit niet gebruikt om het teken van het getal aan te geven, maar om de waarde 2.31Dankzij deze extra bit, heeft het bereik van unsigned integers een bereik van 0 tot 4294967295. Voor getallen kleiner dan 2147483647 lijken unsigned integers op signed integers, maar voor getallen groter dan 2147483647 moet bit 31 (dat altijd 0 is in signed integers) worden gebruikt.

Wanneer een unsigned integer wordt geconverteerd naar een string, worden alleen de geldige bits geretourneerd.

Let op:Alle gehele getallen worden standaard opgeslagen als signed integers. Alleen ECMAScript bitwise operators kunnen unsigned integers creëren.

Bitwise NOT

De bitwise NOT wordt weergegeven met het negatieve teken (~) en is een van de weinige operators in ECMAScript die betrekking hebben op binaire wiskunde.

De NOT-bewerking van bitbewerking is een proces van drie stappen:

  1. Converteer de operanden naar een 32-bits getal
  2. Converteer een binair getal naar zijn binair complement
  3. Converteer een binair getal naar een floating-point getal

Bijvoorbeeld:

var iNum1 = 25;		//25 is gelijk aan 00000000000000000000000000011001
var iNum2 = ~iNum1;	//Convert to 11111111111111111111111111100110
alert(iNum2);		//Uitvoer "-26"

De NOT-bewerking van bitbewerking is eigenlijk het negatieve van het getal en vervolgens 1 minder, dus 25 wordt -26. Je kunt ook hetzelfde resultaat krijgen met de volgende methode:

var iNum1 = 25;
var iNum2 = -iNum1 -1;
alert(iNum2);	//Uitvoer "-26"

AND-bewerking van bitbewerking

De AND-bewerking van bitbewerking wordt weergegeven door het symbool (&), voert de berekening direct uit op de binair vorm van het getal. Het rangschikt de cijfers van elke getal en voert de AND-bewerking uit op dezelfde positie van de twee cijfers met de volgende regels:

Cijfers in het eerste getal Cijfers in de tweede getal Resultaat
1 1 1
1 0 0
0 1 0
0 0 0

Bijvoorbeeld, om de AND-bewerking van de getallen 25 en 3 uit te voeren, is de code als volgt:

var iResult = 25 & 3;
alert(iResult);	//Uitvoer "1"

Het resultaat van de AND-bewerking van 25 en 3 is 1. Waarom? Analyseer als volgt:

 25 = 0000 0000 0000 0000 0000 0000 0001 1001
  3 = 0000 0000 0000 0000 0000 0000 0000 0011
---------------------------------------------
AND = 0000 0000 0000 0000 0000 0000 0000 0001

Kun je zien dat er in 25 en 3 slechts één cijfer (cijfer 0) is dat 1 bevat, dus de andere cijfers genereren allemaal 0, dus het resultaat is 1.

OR-bewerking van bitbewerking

De OR-bewerking van bitbewerking wordt weergegeven door het symbool (|), en voert de berekening direct uit op de binair vorm van het getal. Bij het berekenen van elk cijfer gebruikt de OR-bewerking de volgende regels:

Cijfers in het eerste getal Cijfers in de tweede getal Resultaat
1 1 1
1 0 1
0 1 1
0 0 0

We gebruiken nog steeds het voorbeeld van de AND-bewerking, de OR-bewerking van 25 en 3, de code ervoor is als volgt:

var iResult = 25 | 3;
alert(iResult);	//Uitvoer "27"

Het resultaat van de OR-bewerking van 25 en 3 is 27:

25 = 0000 0000 0000 0000 0000 0000 0001 1001
 3 = 0000 0000 0000 0000 0000 0000 0000 0011
--------------------------------------------
OR = 0000 0000 0000 0000 0000 0000 0001 1011

Kun je zien dat in de twee getallen, er zijn 4 cijfers die 1 bevatten, die aan het resultaat worden doorgegeven. De binaire code 11011 is gelijk aan 27.

Bit-bewerking XOR

De bit-bewerking XOR wordt weergegeven door het symbool (^), natuurlijk, wordt het ook direct op de binairvorm uitgevoerd. XOR is verschillend van OR, het retourneert alleen 1 als er maar één cijfer is dat 1 bevat. Het waarheids tabel is als volgt:

Cijfers in het eerste getal Cijfers in de tweede getal Resultaat
1 1 0
1 0 1
0 1 1
0 0 0

De XOR-bewerking tussen 25 en 3, de code erachter is:

var iResult = 25 ^ 3;
alert(iResult); // uitvoer "26"

Het resultaat van de XOR-bewerking tussen 25 en 3 is 26:

 25 = 0000 0000 0000 0000 0000 0000 0001 1001
  3 = 0000 0000 0000 0000 0000 0000 0000 0011
---------------------------------------------
XOR = 0000 0000 0000 0000 0000 0000 0001 1010

Men kan zien dat er in twee getallen samen 4 cijfers zijn die 1 bevatten, deze cijfers worden doorgegeven aan het resultaat. De binaircode 11010 is gelijk aan 26.

De linker verplaatsing

De linker verplaatsingsoperator wordt weergegeven door twee kleinere dan-tekenen (<<). Hij verplaatst alle cijfers van een getal naar links met het指定的 aantal. Bijvoorbeeld, als je het getal 2 (gelijk aan binair 10) naar links verplaatst met 5 bits, wordt het 64 (gelijk aan binair 1000000):

var iOld = 2; // gelijk aan binair 10
var iNew = iOld << 5; // gelijk aan binair 1000000 decimaal 64

Let op:Bij het links verplaatsen van cijfers, ontstaan er 5 lege posities aan de rechterkant van het getal. De linker verplaatsing vult deze posities met 0's, zodat het resultaat een volledig 32-bits getal blijft.

Getal 2 links verschuiven

Let op:De linker verplaatsing behoudt het tekenbit van het getal. Bijvoorbeeld, als je -2 naar links verplaatst met 5 bits, krijg je -64, niet 64. 'Is het tekenbit nog steeds op de 32e positie opgeslagen?' Ja, maar dit gebeurt in ECMAScript achtergrond, ontwikkelaars kunnen de 32e positie niet direct benaderen. Zelfs als je een negatief getal in binair stringvorm afdrukt, wordt het weergegeven als een min-teken (bijvoorbeeld, -2 wordt weergegeven als -10).

De gesigneerde rechterverplaatsing

De gesigneerde rechterverplaatsingsoperator wordt weergegeven door twee grotere dan-tekenen (>>). Hij verplaatst alle cijfers van een 32-bits getal naar rechts, terwijl hij het teken van het getal (plus of min) behoudt. De gesigneerde rechterverplaatsingsoperator is het tegenovergestelde van de linker verplaatsing. Bijvoorbeeld, als je 64 naar rechts verplaatst met 5 bits, wordt het 2:

var iOld = 64; // is gelijk aan binair 1000000
var iNew = iOld >> 5; // is gelijk aan binair 10 decimaal 2

Opnieuw zal het verschuiven van cijfers lege posities veroorzaken. Deze keer bevinden zich de lege posities aan de linkerkant van het getal, maar na het signaalbit. ECMAScript vult deze lege posities met de waarde van het signaalbit, om een volledig getal te creëren, zoals weergegeven in de onderstaande figuur:

Getal 64 rechtshands verschuiven

Unsigned right shift operator

De unsigned right shift operator wordt weergegeven door drie grotere dan tekens (>>>), die de hele 32-bits getallenrepresentatie naar rechts verplaatsen. Voor positieve getallen is het resultaat van de unsigned right shift operator hetzelfde als dat van de signed right shift operator.

Met het voorbeeld van de signed right shift operator, als men 64 naar rechts shift door 5, wordt dit 2:

var iOld = 64; // is gelijk aan binair 1000000
var iNew = iOld >>> 5; // is gelijk aan binair 10 decimaal 2

Voor negatieve getallen is het echter anders.

De unsigned right shift operator vult alle lege posities met 0. Voor positieve getallen is dit hetzelfde als de signed right shift operator, maar voor negatieve getallen wordt het getal als een positief getal behandeld.

Omdat het resultaat van de unsigned right shift operator een 32-bits positief getal is, resulteert de unsigned right shift operator voor negatieve getallen altijd in een zeer groot getal. Bijvoorbeeld, als men -64 naar rechts shift door 5, krijgt men 134217726. Hoe komt men tot dit resultaat?

Om dit te bereiken, moet men het getal converteren naar een unsigned equivalente vorm (hoewel het getal zelf nog steeds signed is), wat men kan verkrijgen met de volgende code:

var iUnsigned64 = -64 >>> 0;

Vervolgens, gebruik het toString() van het Number-type om zijn ware bitrepresentatie te verkrijgen, met een basis van 2:

alert(iUnsigned64.toString(2));

Dit genereert 11111111111111111111111111000000, wat de binaire complementrepresentatie van het getal -64 is, maar het is gelijk aan het unsigned getal 4294967232.

Om deze reden moet men voorzichtig zijn met het gebruik van de unsigned right shift operator.