1. Bitvis venstreforskyvning
Java har også 3 bitvise skiftoperatorer : Hvis du virkelig trenger det, kan du ganske enkelt flytte alle bitene til et tall flere posisjoner til venstre eller høyre.
For å flytte bitene til et tall til venstre, trenger du den bitvise venstre skiftoperatoren . Slik er det skrevet:
a << b
Hvor a
er tallet hvis biter blir forskjøvet, og b
er et tall som indikerer hvor mange ganger bitene til tallet skal forskyves a
til venstre. Under denne operasjonen er bitene av lav orden som legges til til høyre, null.
Eksempler:
Eksempel | Resultat |
---|---|
|
|
|
|
|
|
|
|
Å flytte ett siffer til venstre har samme effekt som å multiplisere et tall med 2.
Vil du multiplisere et tall med 16? 16 er det samme som 2 4 . Så du flytter tallet 4 sifre til venstre
2. Bitvis skift til høyre
Bits kan også flyttes til høyre. For å gjøre dette, bruk bitvis høyre skiftoperator . Slik er det skrevet:
a >> b
Hvor a
er tallet hvis biter blir forskjøvet, og b
er antall ganger bitene til tallet skal flyttes a
til høyre.
Eksempler:
Eksempel | Resultat |
---|---|
|
|
|
|
|
|
|
|
Å flytte ett siffer til høyre har samme effekt som å dele et tall med 2.
Under denne operasjonen er bitene av høy orden som legges til til venstre, null, men ikke alltid !
Biten lengst til venstre i et fortegnet tall kalles fortegnsbiten : hvis tallet er positivt, er det 0
; men hvis tallet er negativt, er denne biten 1
.
Når bitene til et tall forskyves til høyre, vil verdien av fortegnsbiten vanligvis også skifte og fortegnet til tallet vil gå tapt. Følgelig, for negative tall (hvor biten lengst til venstre er 1
), får denne biten spesialbehandling. Når du flytter bitene til et tall til høyre, 0
legges a til venstre hvis biten lengst til venstre var 0
, og a 1
legges til venstre hvis biten lengst til venstre var 1
.
Men i eksemplet ovenfor ser det ikke ut til at det er resultatet. Hvorfor? Fordi heltalls bokstaver er int
s, og betyr faktisk . Det vil si at biten lengst til venstre er null.0b11111111
0b00000000000000000000000011111111
Mange programmerere er frustrerte over denne høyreskiftadferden og foretrekker at tallet alltid er polstret med nuller. Så Java la til en annen høyreskiftoperatør .
Slik er det skrevet:
a >>> b
Hvor a
er tallet hvis biter blir forskjøvet, og b
er antall ganger bitene til tallet skal flyttes a
til høyre. Denne operatoren legger alltid til nuller til venstre, uavhengig av den opprinnelige verdien av fortegnsbiten til tallet a
.
3. Arbeide med flagg
Programmerere opprettet et nesten helt nytt fagfelt på grunnlag av bitvise og skiftoperasjoner: arbeid med flagg.
Når datamaskiner hadde svært lite minne, var det svært populært å stappe mye informasjon inn i et enkelt nummer. Et tall ble behandlet som en rekke biter: en int er 32 biter, og en long er 64 biter.
Du kan skrive mye informasjon i et slikt tall, spesielt hvis du trenger å lagre logiske ( true
eller false
) verdier. En singel long
er som en boolean
matrise bestående av 64 elementer. Disse bitene ble kalt flagg og ble manipulert ved hjelp av følgende operasjoner:
-
sette flagg(gjør en bestemt bit lik
1
) -
tilbakestill flagg(gjør en bestemt bit lik
0
) -
sjekk flagget(sjekk verdien av en bestemt bit)
Og her er hvordan det gjøres med bitvise operatører.
Sette et flagg
For å sette en spesifikk bit til 1
, må du utføre en bitvis ELLER-operasjon mellom tallet hvis bit du vil sette og et spesiallaget tall, der bare den biten er 1
.
Anta for eksempel at du har nummeret 0b00001010
og at du må sette den 5. biten til 1
. I så fall må du:
0b00001010 | 0b00010000 = 0b00011010
Hvis den 5. biten hadde blitt satt til én allerede, ville ingenting ha endret seg.
Generelt kan operasjonen med å sette et flagg skrives som følger
a | (1 << b)
Hvor a
er tallet hvis bit vil bli satt til 1
. Og b
er posisjonen til bittet som skal stilles inn. Å bruke venstre skiftoperatør er super praktisk her, siden du umiddelbart kan se hvilken bit vi jobber med.
Tilbakestille et flagg
For å tilbakestille en spesifikk bit (dvs. sette den til 0
) uten å forstyrre andre biter, må du utføre en &
operasjon mellom nummeret hvis bit du vil tilbakestille (dvs. satt til 0
) og et spesiallaget tall, der alle bitene er like 1
unntatt for biten du vil tilbakestille.
Anta for eksempel at du har nummeret 0b00001010
og at du må sette den fjerde biten til 0
. I så fall må du:
0b00001010 & 0b11110111 = 0b00000010
Hvis den fjerde biten allerede hadde blitt satt til null, ville ingenting ha endret seg.
Generelt kan operasjonen med å tilbakestille et flagg skrives som følger
a & ~(1 << b)
Hvor a
er nummeret hvis bit vil bli tilbakestilt til 0
. Og b
er posisjonen til biten som skal ryddes.
For å få et tall der alle bitene er 1
unntatt den vi ønsker skal være null, skifter vi først 1 b posisjoner til venstre, og bruker deretter den bitvise NOT
operatoren for å invertere resultatet.
Sjekker et flagg
I tillegg til å sette eller tilbakestille et spesifikt flagg, trenger du noen ganger bare å sjekke om et gitt flagg er satt, dvs. om en viss bit er lik 1
. Dette er ganske enkelt å gjøre med litt &
.
Anta for eksempel at du må sjekke om den fjerde biten er satt til 1
i tallet 0b00001010
. Da må du gjøre dette:
if ( (0b00001010 & 0b00001000) == 0b00001000 )
Generelt kan operasjonen med å sjekke et flagg skrives som følger
(a & (1 << b)) == (1 << b)
Hvor a
er nummeret hvis bit blir sjekket. Og b
er posisjonen til bittet som skal sjekkes.
4. Kryptering
Den bitvise XOR
operasjonen brukes ofte av programmerere for enkel kryptering. Generelt ser slik kryptering slik ut:
result = number ^ password;
Hvor number
er dataene vi ønsker å kryptere, password
er et spesialnummer som brukes som "passord" for dataene, og result
er det krypterte nummeret.
number == (number ^ password) ^ password;
Det viktige her er at når operatoren XOR
brukes på et tall to ganger, produserer den det opprinnelige tallet, uavhengig av "passordet".
For å gjenopprette number
fra encrypted result
, trenger du bare å utføre operasjonen på nytt:
original number = result ^ password;
Eksempel:
class Solution
{
public static int[] encrypt(int[] data, int password)
{
int[] result = new int[data.length];
for (int i = 0; i < data.length; i++)
result[i] = data[i] ^ password;
return result;
}
public static void main(String[] args)
{
int[] data = {1, 3, 5, 7, 9, 11};
int password = 199;
// Encrypt the array of data
int[] encrypted = encrypt(data, password);
System.out.println(Arrays.toString(encrypted));
// Decrypt the array of data
int[] decrypted = encrypt(encrypted, password);
System.out.println(Arrays.toString(decrypted));
}
}
GO TO FULL VERSION