Understanding bitvis operatører
30
Del
12
Del
Dette Cyber mandag Envato Tuts + kurs vil bli redusert til bare $ 3. Ikke gå glipp av.
bitvis operatører er de merkelige operatører som kan se vanskelig å forstå ... men ikke noe mer! Dette lett å følge artikkelen vil hjelpe deg å forstå hva de er og hvordan du bruker dem, med et par praktiske eksempler i tillegg til å vise deg når og hvorfor du trenger dem.
Innledning
bitvis operatører er operatører (akkurat som +, *, & &, etc.) som opererer på ints og uints på den binære nivå. Dette betyr at de ser direkte på binære siffer eller biter av et heltall. Dette høres skummelt, men i sannhet bitvis operatører er ganske lett å bruke og også ganske nyttig!
Det er viktig, men at du har en forståelse av binære tall og heksadesimale tall. Hvis du ikke gjør det, kan du sjekke ut denne artikkelen - det vil virkelig hjelpe deg! Nedenfor er et lite program som lar deg prøve ut de forskjellige bitvis operatører.
Ikke bekymre deg hvis du ikke forstår hva som skjer ennå, det vil alle være klar snart ...
Erkjenner bitvis operatører
La oss ta en titt på bitvis operatører som AS3 forsyninger. Mange andre språk er ganske like (for eksempel, Javascript og Java har praktisk talt identiske operatører):
& (bitvis AND)
| (bitvis OR)
~ (bitvis NOT)
^ (bitvis XOR)
< < (bitvis venstre shift)
> > (bitvis høyre shift)
> > > (bitvis usignert høyre shift)
& = (bitvis AND oppdrag)
| = (bitvis OR oppdrag)
^ = (bitvis XOR oppdrag)
< li> < < = (bitvis venstre shift og tildeling)
> > = (bitvis høyre shift og oppdrag)
> > > = (bitvis usignert høyre shift og tildeling)
Det er et par ting du bør ta fra dette: Først noen bitvis operatører ligne operatører du har brukt før (& vs. & &, | vs . ||). Dette er fordi de er For det andre mest bitvis operatører kommer med en sammensatte oppdrag skjema Up først: bitvis AND operatør, &. En rask heads-up om: normalt, ints og uints ta opp 4 byte eller 32 biter av plass. Dette betyr at hver int eller uint lagres som 32 binære siffer. For å få til denne opplæringen, vil vi late som noen ganger at ints og uints bare ta opp en byte og har bare 8 binære siffer &.; Operatøren sammen hvert binære siffer i to heltall, og returnerer en ny helt tall, med en 1 hvor begge numrene hadde en 1 og en 0 noe annet sted. Et diagram er verdt tusen ord, så her er en til å klare ting opp. Det representerer gjør 37 & 23, noe som tilsvarer 5. Legg merke til hvordan hver binære siffer i 37 og 23 sammenlignes, og resultatet har en uansett hvor både 37 og 23 hadde en 1, og resultatet har en 0 ellers. Anmeldelser En vanlig måte å tenke på binære siffer er like sant eller usant. Det vil si, en tilsvarer sant og 0 er ekvivalent med falsk. Dette gjør &Co. operatøren være mer fornuftig Når vi sammenligner to booleans, vi vanligvis gjør boolean1 &. & boolean2. Det uttrykket er bare sant dersom begge boolean1 og boolean2 er sanne. På samme måte, Heltall1 &Co. integer2 er tilsvarende, som &Co. Operatøren bare utganger en 1 når begge binære sifrene i våre to heltall er 1. Her er en tabell som representerer den ideen: En pen liten bruk av & operatøren er å sjekke om et tall er partall eller oddetall. For heltall kan vi bare sjekke lengst til høyre bit (også kalt den minst signifikante bit) å avgjøre om heltall er oddetall eller partall. Dette er fordi når du konverterer å basere 10, lengst til høyre bit representerer to 0 eller 1. Når lengst til høyre bit er 1, vet vi at våre tall er rart siden vi legger en til en haug med krefter to som vil alltid bli enda. Når lengst til høyre bit er 0, vet vi våre tall vil bli enda, siden det bare består av å legge opp en haug med partall Her er et eksempel:. På min datamaskin, denne metoden var ca 66% raskere enn å bruke randInt% 2 for å sjekke for like og ulike tall. ! Det er litt av en ytelsesøkning Up neste er den bitvis OR operatør, |. Som du kanskje har gjettet, den | operatøren er til || Operatøren som &Co. Operatøren er til &Co. &Co. operatør. Den | Operatøren sammen hver binære siffer over to heltall og gir tilbake en 1 hvis enten La oss ta en titt på det samme eksemplet som før, bortsett fra nå bruker | operatøren i stedet for &Co. operatør. Vi overvåker nå gjør 37 | 23 som tilsvarer 55: Vi kan dra nytte av & og | operatører å tillate oss å passere flere alternativer til en funksjon i en enkelt int. La oss ta en titt på en mulig situasjon. Vi bygger et pop-up vindu klasse. På bunnen av det, kan vi ha en ja, nei, OK, eller Avbryt-knappen eller en kombinasjon av disse - hvordan skal vi gjøre dette? Her er den harde måten: Er dette fryktelig? Nei, men det er dårlig, hvis du er en programmerer, å måtte se opp rekkefølgen av argumentene hver gang du kaller funksjonen. Det er også irriterende - for eksempel hvis du bare ønsker å vise på Avbryt-knappen, må du sette alle andre Booleans til false La oss bruke det vi har lært om &. og | for å gjøre en bedre løsning: Hvordan ville en programmerer samtale funksjonen så på Ja, Nei knappen og Avbryt-knappen viser? Liker du dette: Hva skjer? Det er viktig å merke seg at våre konstanter i det andre eksemplet er alle krefter to. Så, hvis vi ser på deres binærform, vil vi merke de alle har ett siffer lik 1, og resten lik 0. Faktisk har de en annen sifret lik 1. Det betyr at uansett hvor vi kombinerer dem med |, vil hver kombinasjon gir oss et unikt nummer. Ser på det på en annen måte, ut resultatet av vår | uttalelse vil være et binært tall med en 1 hvor våre alternativer hadde 1. For vår nåværende eksempel har vi PopupWindow.YES | PopupWindow.NO | PopupWindow.CANCEL som tilsvarer 1 | 2 | 8 som omskrevet i binært er 00000001 | 00000010 | 00001000 som gir oss et resultat av 00001011. Nå, i vår showPopup () -funksjonen, bruker vi & å sjekke hvilke alternativer ble vedtatt i for eksempel når vi sjekker knapper og amp.; JA, alle biter i YES er lik 0 unntatt den aller lengst til høyre en. Så er vi i hovedsak å sjekke om den lengst til høyre bit i knapper er en 1 eller ikke. Hvis det er, knapper og amp; JA vil ikke lik 0 og noe i hvis setningen vil bli henrettet. Derimot, hvis lengst til høyre bit i knapper er 0, knapper & JA vil tilsvare 0, og hvis setningen vil ikke bli henrettet. bitvis IKKE operatør er litt annerledes enn de to vi har sett på så langt. I stedet for å ta et helt tall på hver side av den, tar det et heltall bare etter den. Dette er akkurat som det! operatør, og ikke overraskende, det gjør en lignende ting. Faktisk like! knipser en boolsk fra tro mot falsk eller vice versa, den ~ operatør reverserer hver binære siffer i et heltall: fra 0 til 1 og 1 til 0: Et raskt eksempel. Si at vi har heltallet 37 eller 00100101. ~ 37 er så 11011010. Hva er basen 10 verdien av dette? Vel ... Nå begynner moroa! Vi kommer til å ta en nærmere titt på binære tall på en datamaskin. La oss starte med den uint. Som nevnt før, er en uint typisk 4 byte eller 32 bits lang, noe som betyr at den har 32 binære siffer. Dette er lett å forstå: å få base 10 verdien vi bare konvertere tallet å basere 10 regelmessig. Vi får alltid et positivt tall. Men hva med int? Den bruker også 32 bits, men hvordan lagrer det negative tall? Hvis du gjettet at det første sifferet brukes til å lagre skiltet, er du på rett vei. La oss ta en titt på toerkomplementet For å finne de to komplement av et binært tall, vi bare snu alle bitene (dvs. gjøre hva ~ operatør gjør) og legge en til resultatet. La oss prøve dette ut en gang: Vi definerer vårt resultat som verdien -37. Hvorfor gjør dette komplisert prosess, og ikke bare snu den aller første bit, og kaller det -37? Vel, la oss ta et enkelt uttrykk 37 + -37. Vi vet alle at dette skal være lik 0, og når vi legger til 37 til sine to komplement, det er hva vi får: Legg merke til at siden våre heltall bare holde åtte binære siffer, 1 i vårt resultat er droppet, og vi ender opp med 0, som vi burde. For å oppsummere, for å finne den negative av et tall, vi bare ta sine to komplement. Vi kan gjøre dette ved å snu alle biter og legge en. Lyst til å prøve dette selv? Legg spor (~ 37 + 1); til en AS3 fil, og deretter kompilere og kjøre den. Du vil se -37 er skrevet ut, slik det skal være Det er også en liten snarvei til å gjøre dette for hånd. Start fra høyre, arbeid mot venstre til du kommer til en 1. Flip alle biter til venstre for denne første 1. Når vi ser på en signert binært tall (med andre ord, en som kan være negative, en int ikke en uint), vi kan se på helt til venstre sifret å fortelle om det er negativt eller positivt. Hvis det er en 0, så antallet er positiv og vi kan konvertere til basen 10 rett og slett ved å beregne sin base 10 verdi. Hvis venstre biten er en 1, så tallet er negativt, så vi tar de to komplement av nummeret for å få den positive verdien og så bare legge til et minustegn. For eksempel, hvis vi har 11110010, vi vet at det er et negativt tall. Vi kan finne det er toer-komplement ved å vippe alle sifrene til venstre for lengst til høyre en, noe som gir oss 00001110. Dette tilsvarer 13, så vi vet 11110010 tilsvarer -13. Vi er tilbake til bitvis operatører, og opp neste er bitvis XOR operatør. Det er ingen tilsvarende boolsk operator til dette ^ operatør ligner på &.; og | operatører i at det tar en int eller uint på begge sider. Når det er beregning av resulterende tallet, er det igjen sammenligner de binære tallene i disse tallene. Hvis den ene eller den andre er en 1, vil det sette en 1 i til resultatet, ellers vil det sette en 0. Det er der navnet XOR, eller "eksklusiv eller" kommer fra. La oss ta en se på vår vanlige eksempel:. ^ operatøren har bruksområder - det er spesielt bra for veksling binære siffer - men vi vil ikke dekke noen praktiske anvendelser i denne artikkelen Vi er nå på bitshift operatører, spesielt bitvis venstre skifte operatør her. Disse fungerer litt annerledes enn før. I stedet for å sammenligne to heltall som &, |, og ^ gjorde, disse operatørene skifte et heltall. På venstre side av operatøren er det hele tall som blir flyttet, og til høyre er hvor mye å skifte fra. Så, for eksempel, 37 < < 3 er skiftende nummer 37 til venstre etter 3 steder. Selvfølgelig, vi jobber med binære representasjon av 37. La oss ta en titt på dette eksempelet (husk, vi er bare nødt til å late som heltall bare har 8 bits i stedet for 32). Her har vi nummer 37 sitter på sin fine blokk med minne 8 bits bredt Ok, la oss skyve alle sifrene over til venstre med 3, som 37. ≪ < 3 ville gjøre: Men nå har vi et lite problem - hva gjør vi med de 3 åpne biter av minnet der vi flyttet sifrene fra Selvfølgelig! Eventuelle tomme plassene er bare erstattet med 0s. Vi ender opp med 00.101.000. Og det er alt som skal til venstre bitshift. Husk at Flash tenker alltid et resultat av en venstre bitshift er en int, ikke en uint. Så hvis du trenger en uint for noen grunn, må du kaste det for en uint som dette: uint (37 < < 3). Dette casting faktisk ikke endre noe av den binære informasjonen, bare hvordan Flash tolker det (hele toerkomplement ting). En interessant funksjon av venstre bitshift er at det er det samme som å multiplisere et tall med to til den shiftAmount-te potens. Så, 37 < < 3 == 37 * Math.pow (2,3) == 37 * 8. Hvis du kan bruke den venstre shift i stedet for Math.pow, vil du se en enorm ytelsesøkning. Du har kanskje lagt merke til at det binære tall vi endte opp med ikke lik 37 * 8. Dette er bare fra vår bruk av bare 8 biter av minne for heltall; hvis du prøver det i Actionscript, vil du få riktig resultat. Eller, prøv det med demoen på toppen av siden Nå som vi forstår venstre bitshift, den neste, høyre bitshift, vil være lett. Alt glir til høyre beløpet vi angir. Den eneste liten forskjellen er hva de tomme biter få fylt med. Hvis vi starter med et negativt tall (et binært tall der venstre biten er en 1), blir alle tomrommene fylt med en . Hvis vi starter med et positivt tall (der den venstre biten, eller mest signifikante bit, er en 0), så alle de tomme plassene er fylt med en 0. Igjen, dette går alt tilbake til toerkomplement. Anmeldelser Selv om dette høres komplisert, det i utgangspunktet bare bevarer tegn på antall starter vi med. Så -8 > > 2 == -2 mens 8 > > 2 == 2. Jeg vil anbefale å prøve dem ut på papir selv Siden >. ≫ er det motsatte av < <, det er ikke overraskende at det å flytte et tall til høyre er det samme som å dele det på to til makten av shiftAmount. Du har kanskje lagt merke til dette fra eksempelet ovenfor. Igjen, hvis du kan bruke dette for å unngå å ringe Math.pow, vil du få en betydelig ytelsesforbedring Vårt endelige bitvis operatør er bitvis usignert høyre shift. Dette er svært lik den vanlige bitvis høyre skift, bortsett fra at alle tomme biter til venstre er fylt med 0s. Dette betyr at resultatet av denne operatoren er alltid et positivt helt tall, og det alltid behandler det hele tall blir flyttet som et usignert heltall. Vi vil ikke kjøre gjennom et eksempel på dette i denne delen, men vi får se en bruk for det svært kort tid. En av de praktiske anvendelser av bitvis operatører i Actionscript 3 er å jobbe med farger, som er lagret vanligvis som uints Standardformatet for farger er å skrive dem i heksadesimal: 0xAARRGGBB - hver bokstav representerer et heksadesimalt siffer.. Her er de to første heksadesimale sifre, som er sammenlignbart med de første åtte binære siffer, representerer vår alpha, eller gjennomsiktighet. De neste åtte bits representerer mengden av rødt i vår farge (slik at et helt tall fra 0 til 255), de neste åtte mengden av grønt, og den siste åtte representerer mengden av blå farge i vår. Uten bitvis operatører, er det ekstremt vanskelig å arbeide med farger i dette formatet - men med dem det er lett Utfordring 1: Finn den mengden blått i en farge: Bruke &! operatør, prøve å finne hvor mye blått i en vilkårlig farge Vi trenger en måte å "slette" eller maskere hele andre data i farger og bare ha den blå komponenten venstre. Det er lett, faktisk! Hvis vi tar farge & 0x000000FF - eller skrevet mer enkelt, farge & 0xFF - vi ender opp med bare den blå komponenten Som du ser ovenfra og du lærte i beskrivelsen av &. operator, en hvilken som helst binære siffer &Co. 0 vil alltid være lik 0, mens noen binære siffer & 1 vil holde sin verdi. Så hvis vi maskere vårt farge av 0xFF som bare har 1s hvor den blå del av vår farge er plassert, og vi ender opp med bare den blå komponenten Challenge. 2: Finn mengden av rødt i en farge: Bruke to bitvis operatører, prøve å finne mengden av rødt i en vilkårlig farge Vi har faktisk to løsninger på dette problemet. En ville være tilbake (farge & 0xff0000) > > 16; og den andre ville være tilbake (farge > > 16) & 0xFF; Dette er svært lik Utfordre en, bortsett fra at vi må skifte vårt svar på et tidspunkt Challenge. 3: Finn gjennomsiktigheten en farge: Ved hjelp av bare én bitvis operatør, prøve å finne alfa til en farge (et heltall fra 0 til 255). Dette er et snev vanskeligere. Vi må være forsiktig med hvilke høyre shift operater vi velger. Fordi vi jobber med lengst til venstre sifrene i et uint, vi ønsker å bruke > > > operatør. Så, er vårt svar slett retur farge > > > 24;. Final Utfordring: Lag en farge fra sine komponenter: Bruke < < og | operatører, ta komponentene i en farge og flette dem inn til en uint. Her har vi å skifte hver komponent til riktig posisjon, og deretter flette dem. Vi ønsker Flash for å behandle det som et usignert heltall, så vi kastet den til en uint: retur uint ((a < < 24) | (r < < 16) | (g < < 8) | b ); Du har kanskje lagt merke til har jeg unnlatt å forklare sammensatte bitvis operatører. Tenk deg har vi et heltall x. Deretter, x = x &Co. 0xFF er den samme som x &Co. = 0xFF, x = x | 256 er det samme som x | = 256, og så videre for resten av sammensatte operatørene Takk for at du leser denne artikkelen.! Jeg håper du nå forstår bitvis operatører og kan utnytte dem i AS3 kode (eller i mange andre språk!). Som alltid, hvis du har noen spørsmål eller kommentarer, vennligst la dem nedenfor. Anmeldelser
noe lignende.
av seg selv. Dette er det samme som hvordan du kan bruke + og + =, - og - =, etc.
The & Operatør
Var randInt: int = int (Math. tilfeldig () * 1000); if (randInt & {". Odd number" trace ();} 1) else {trace ("Even nummer.");}
The | Operatør
av dem er 1. Igjen, dette ligner på || . operatør med booleans
Flags: A Bruk av & og | Operatører
public class PopupWindow strekker Sprite {//Variabler, Constructor, osv ... public static void showPopup (yesButton: Boolean, noButton: Boolean, okayButton: Boolean, Avbryt-: Boolean) {if (yesButton) {//legge JA knappen} if (noButton) {//legge NO Button} //og så videre for resten av knappene}}
public class PopupWindow strekker Sprite {public static konst JA: int = 1; public static konst NEI: int = 2; public static konst GREIT: int = 4; public static konst CANCEL: int = 8; public static void showPopup (knapper: int) {if (knapper & YES) {//legge JA knappen} if (knapper & NO) {//legge NO knappen}}}
PopupWindow.show (PopupWindow.YES | PopupWindow.NO | PopupWindow.CANCEL);
The ~ Operator
toerkomplementet, uint vs. int, og mer!
system for lagring av binære tall. Mens vi vil ikke gå inn i alle detaljene her, er en to komplement systemet brukes fordi det gjør binær aritmetikk enkelt.
The ^ Operator Anmeldelser
The < < Operatør
The >! ≫ Operatør
The >. ≫ > Operatør
Bruke bitvis operatører å jobbe med farger
offentlig funksjon findBlueComponent (farge: uint):. uint {! //Din kode her}
offentlig funksjon findRedComponent. (farge: uint): {! //Din kode her} uint
offentlig funksjon findAlphaComponent (farge: uint): {! //Din kode her} uint
offentlig funksjon createColor (a: uint, r: uint, g: uint, b: uint): uint {! //Din kode her}
Sammensatte Operatører
Konklusjon