JavaRush /Java Blog /Random-TL /Bitwise na operasyon sa Java

Bitwise na operasyon sa Java

Nai-publish sa grupo
Marahil ay pamilyar ka sa salitang "matalo". Kung hindi, kilalanin natin ito :) Ang kaunti ay ang pinakamababang yunit ng pagsukat ng impormasyon sa isang computer. Ang pangalan nito ay nagmula sa Ingles na " binary digit " - "binary number". Ang isang bit ay maaaring ipahayag bilang isa sa dalawang numero: 1 o 0. Mayroong isang espesyal na sistema ng numero batay sa mga isa at mga zero - binary. Hindi kami susubok sa kagubatan ng matematika at tandaan lamang na anumang numero sa Java ay maaaring ma-convert sa binary form nito. Upang gawin ito kailangan mong gumamit ng mga klase ng wrapper. Mga pagpapatakbo ng bitwise - 1Halimbawa, narito kung paano ito gawin para sa isang numero int:
public class Main {

   public static void main(String[] args) {

       int x = 342;
       System.out.println(Integer.toBinaryString(x));
   }
}
Output ng console:

101010110
Ang 1010 10110 (Nagdagdag ako ng puwang para sa pagiging madaling mabasa) ay ang bilang na 342 sa binary. Talagang hinati namin ang numerong ito sa mga indibidwal na piraso - mga zero at isa. Sa kanila tayo makakapagsagawa ng mga operasyong tinatawag na bitwise.
  • ~— bitwise “HINDI” operator.

Gumagana ito nang napakasimple: dumadaan ito sa bawat bit ng aming numero at binabago ang halaga nito sa kabaligtaran: mga zero sa isa, isa sa mga zero. Kung ilalapat natin ito sa ating numerong 342, ito ang makukuha natin: 101010110 - ang numerong 342 sa binary 010101001 - ang resulta ng expression ~342 Ngunit dahil ang isang int variable ay tumatagal ng 4 na bytes, i.e. 32 bits, sa katunayan, ang numero sa variable ay naka-imbak bilang: 00000000 00000000 00000001 01010110- ang numero 342 sa isang variable ng uri int sa java 11111111 11111111 11111110 10101001- ang resulta ng expression ~342 sa java Subukan nating gawin ito sa pagsasanay:
public class Main {

   public static void main(String[] args) {

       int x = 342;
       System.out.println(Integer.toBinaryString(~x));
   }
}
Output ng console:
11111111111111111111111010101001
  • &— bitwise operator “AT”

Tulad ng nakikita mo, ito ay nakasulat na halos kapareho ng lohikal na "AT" ( &&). Ang operator &&, gaya ng naaalala mo, ay babalik truelamang kung ang parehong mga operand ay totoo. Gumagana ang Bitwise &sa katulad na paraan: inihahambing nito ang dalawang numero nang paunti-unti. Ang resulta ng paghahambing na ito ay ang ikatlong numero. Halimbawa, kunin natin ang mga numerong 277 at 432: 100010101 - ang numero 277 sa binary form 110110000 - ang numero 432 sa binary form Susunod, &inihahambing ng operator ang unang bit ng itaas na numero sa unang bit ng mas mababang isa. Dahil ito ay isang "AT" na operator, ang resulta ay magiging katumbas ng 1 lamang kung ang parehong mga bit ay katumbas ng 1. Sa lahat ng iba pang mga kaso, ang resulta ay magiging 0. 100010101 & 110110000 _______________ 100010000 - resulta ng trabaho & Inihambing muna namin ang mga unang bit ng dalawang numero sa isa't isa, pagkatapos ay pangalawang bit, pangatlo, atbp. Tulad ng nakikita mo, sa dalawang kaso lamang ang parehong mga bit sa mga numero na katumbas ng 1 (ang una at ikalimang bit). Ang resulta ng lahat ng iba pang mga paghahambing ay 0. Samakatuwid, sa huli nakuha namin ang numerong 100010000. Sa sistema ng decimal, tumutugma ito sa numerong 272. Suriin natin:
public class Main {

   public static void main(String[] args) {
       System.out.println(277&432);
   }
}
Output ng console:

272
  • |- bitwise “O”. Ang prinsipyo ng operasyon ay pareho - inihambing namin ang dalawang numero nang paunti-unti. Ngayon lamang kung ang kahit isa sa mga bit ay katumbas ng 1, ang resulta ay magiging katumbas ng 1. Tingnan natin ang parehong mga numero - 277 at 432:
100010101 | . | _ Ang resulta ng trabaho ay ang numero 110110101. Sa sistema ng decimal ito ay tumutugma sa numero 437. Suriin natin:
public class Main {

   public static void main(String[] args) {
       System.out.println(277|432);
   }
}
Output ng console:

437
Binilang namin ang lahat ng tama! :)
  • ^- bitwise exclusive OR (kilala rin bilang XOR)
Hindi pa kami nakatagpo ng ganoong operator. Ngunit walang kumplikado tungkol dito. Mukhang isang regular na "o". Ang pagkakaiba ay isa: ang ordinaryong "o" ay nagbabalik truekung ang hindi bababa sa isang operand ay totoo. Ngunit hindi kinakailangan isa - kung pareho ang naroroon true- kung gayon ang resulta true. Ngunit ang eksklusibong "o" ay babalik truelamang kung ang isa sa mga operand ay totoo. Kung ang parehong mga operand ay totoo, ang isang regular na "o" ay babalik true("kahit isa ay totoo"), ngunit isang eksklusibo o babalik false. Kaya naman tinawag itong exclusive. Alam ang prinsipyo ng mga nakaraang bitwise na operasyon, malamang na madali mong maisagawa ang 277^432 na operasyon sa iyong sarili. Ngunit mas mabuting pag-isipan natin itong muli :) 100010101 ^ 110110000 _______________ 010100101 - ang resulta ng gawain ^ Narito ang aming resulta. Ang mga bit na iyon na pareho sa parehong mga numero ay nagbalik ng 0 (ang "isa sa" formula ay hindi gumana). Ngunit ang mga nakabuo ng isang pares na 0-1 o 1-0 sa huli ay naging isang yunit. Bilang resulta, nakuha namin ang numerong 010100101. Sa sistema ng decimal, tumutugma ito sa numerong 165. Tingnan natin kung tama ang pagkalkula namin:
public class Main {

   public static void main(String[] args) {
       System.out.println(277^432);
   }
}
Output ng console:

165
Super! Ang lahat ay eksakto tulad ng naisip namin :) Ngayon ang oras upang maging pamilyar sa mga operasyon na tinatawag na bit shifts. Ang pangalan, sa prinsipyo, ay nagsasalita para sa sarili nito. Kukuha tayo ng ilang numero at ililipat ang mga bit nito pakaliwa at kanan :) Tingnan natin kung ano ang hitsura nito:

Lumipat pakaliwa

Ang kaliwang shift ng mga bit ay ipinahiwatig ng tanda << Halimbawa:
public class Main {

   public static void main(String[] args) {
       int x = 64;//meaning
       int y = 3;//quantity

       int z = (x << y);
       System.out.println(Integer.toBinaryString(x));
       System.out.println(Integer.toBinaryString(z));
   }
}
Sa halimbawang ito, ang numero x=64ay tinatawag na halaga. It is its bits that we will shift. Ililipat namin ang mga bits sa kaliwa (ito ay maaaring matukoy sa pamamagitan ng direksyon ng pag-sign <<) Sa binary system, ang numero 64 = 1000000 Ang numero y=3ay tinatawag na dami. Sinasagot ng dami ang tanong na "ilang bits sa kanan/kaliwa ang dapat ilipat ang mga bits ng isang numero x?" Sa aming halimbawa, ililipat namin ang mga ito ng 3 bits sa kaliwa. Upang gawing mas malinaw ang proseso ng paglilipat, tingnan natin ang larawan. Sa aming halimbawa gumagamit kami ng mga numero ng uri ng int. IntSinasakop ang 32 bits ng memorya ng computer. Ito ang hitsura ng aming orihinal na numero 64: Mga pagpapatakbo ng bitwise - 2At ngayon kami, sa literal na kahulugan ng salita, kunin ang bawat isa sa aming mga bit at ilipat ito sa kaliwa ng 3 mga cell: Mga pagpapatakbo ng bitwise - 3Ito ang nakuha namin. Tulad ng nakikita mo, lahat ng aming mga bit ay lumipat, at 3 higit pang mga zero ang naidagdag mula sa labas ng hanay. 3 - dahil nagshi-shift kami ng 3. Kung nagshi-shift kami ng 10, 10 zero ang idadagdag. Kaya ang expression x << yay nangangahulugang "ilipat ang mga bit ng isang numero хy cell sa kaliwa." Ang resulta ng aming expression ay ang bilang na 1000000000, na sa decimal system ay katumbas ng 512. Suriin natin:
public class Main {

   public static void main(String[] args) {
       int x = 64;//meaning
       int y = 3;//quantity

       int z = (x << y);
       System.out.println(z);
   }
}
Output ng console:

512
Tama iyan! Sa teorya, ang mga bit ay maaaring ilipat nang walang katiyakan. Ngunit dahil mayroon kaming numero int, mayroon lamang 32 na mga cell na magagamit. Sa mga ito, 7 ay okupado na ng bilang na 64 (1,000,000). Samakatuwid, kung gagawa tayo, halimbawa, ng 27 na paglilipat sa kaliwa, ang tanging unit natin ay mawawala sa saklaw at "i-overwrite". Mga zero na lang ang mananatili!
public class Main {

   public static void main(String[] args) {
       int x = 64;//meaning
       int y = 26;//quantity

       int z = (x << y);
       System.out.println(z);
   }
}
Output ng console:

0
Tulad ng inaasahan namin, ang isa ay lumampas sa 32 bit na mga cell at nawala. Nakakuha kami ng 32-bit na numero na binubuo lamang ng mga zero. Mga pagpapatakbo ng bitwise - 4Naturally, sa decimal system ito ay tumutugma sa 0. Isang simpleng panuntunan para sa pag-alala sa mga left shift: Sa bawat kaliwang shift, ang numero ay i-multiply sa 2. Halimbawa, subukan nating kalkulahin ang resulta ng expression na walang mga larawan na may bits. 111111111 << 3 Kailangan natin upang i-multiply ang numerong 111111111 sa 2 nang tatlong beses. Bilang resulta, makakakuha tayo ng 888888888. Isulat natin ang code at suriin ito:
public class Main {

   public static void main(String[] args) {
       System.out.println(111111111 << 3);
   }
}
Output ng console:

888888888

Mga tamang shift

Ang mga ito ay ipinahiwatig ng tanda >>. Ginagawa nila ang parehong bagay, tanging sa kabilang direksyon! :) Huwag nating baguhin ang gulong at subukang gawin ito gamit ang parehong numero int 64.
public class Main {

   public static void main(String[] args) {
       int x = 64;//meaning
       int y = 2;//quantity

       int z = (x >> y);
       System.out.println(z);
   }
}
Mga pagpapatakbo ng bitwise - 5Mga pagpapatakbo ng bitwise - 6Bilang resulta ng paglilipat ng 2 sa kanan, ang dalawang extreme zero ng aming numero ay lumabas sa hanay at nabura. Nakuha namin ang numero 10000, na sa sistema ng decimal ay tumutugma sa numero 16. Output sa console:

16
Isang simpleng panuntunan para sa pag-alala ng mga tamang shift: Ang bawat right shift ay nahahati sa dalawa, itinatapon ang anumang natitira. Halimbawa, 35 >> 2 nangangahulugan ito na kailangan nating hatiin ang 35 sa 2 2 beses, itinatapon ang natitira 35/2 = 17(itinatapon ang natitira 1) 17:2 = 8(itinatapon ang natitira 1) Ang kabuuan 35 >> 2ay dapat na katumbas ng 8. Suriin:
public class Main {

   public static void main(String[] args) {
       System.out.println(35 >> 2);
   }
}
Output ng console:

8

Nangunguna sa mga operasyon sa Java

Habang nagsusulat o nagbabasa ka ng code, madalas kang makakatagpo ng mga expression kung saan ang ilang mga operasyon ay isinasagawa nang sabay-sabay. Napakahalaga na maunawaan kung anong pagkakasunud-sunod ang kanilang gagawin, kung hindi man ang resulta ay maaaring hindi inaasahan. Dahil maraming mga operasyon sa Java, lahat sila ay pinaghiwalay sa isang espesyal na talahanayan:

Pangunahing Operator

Mga operator Karapatan sa pangunguna
postfix expr++ expr--
unary ++expr --expr +expr ~ !
Multiplicative * / %
pandagdag + -
shift << >> >>>
pamanggit < > <= >=halimbawa ng
pagkakapantay-pantay == !=
bitwise AT &
bitwise eksklusibo O ^
bitwise inclusive O |
lohikal AT &&
lohikal O ||
ternary ? :
takdang-aralin = += -= *= /= %= &= ^= |= <<= >>= >>>=
Ang lahat ng mga operasyon ay isinasagawa mula kaliwa hanggang kanan, ngunit isinasaalang-alang ang kanilang priyoridad. Halimbawa, kung isusulat natin: int x = 6 - 4/2; una ang operasyon ng paghahati (4/2) ay isasagawa. Bagama't siya ay pangalawa sa linya, mas mataas ang priyoridad niya. Binabago ng mga panaklong o square bracket ang anumang priyoridad sa maximum. Malamang naaalala mo ito mula sa paaralan. Halimbawa, kung idaragdag mo ang mga ito sa isang expression: int x = (6 - 4)/2; isasagawa muna ang pagbabawas, dahil kinakalkula ito sa mga panaklong. Ang lohikal na operator ay may &&medyo mababang priyoridad, tulad ng makikita mula sa talahanayan. Samakatuwid, kadalasan ito ay huling isasagawa. Halimbawa: boolean x = 6 - 4/2 > 3 && 12*12 <= 119; Ang expression na ito ay isasagawa tulad nito:
  • 4/2 = 2

    boolean x = 6 - 2 > 3 && 12*12 <= 119;
  • 12*12 = 144

    boolean x = 6 - 2 > 3 && 144 <= 119;
  • 6-2 = 4

    boolean x = 4 > 3 && 144 <= 119;
  • Susunod na isasagawa ang mga operator ng paghahambing:

    4 > 3 = true

    boolean x = true && 144 <= 119;
  • 144 <= 119 = false

    boolean x = true && false;
  • At sa wakas, ang huling operator ay isasagawa &&.

    boolean x = true && false;

    boolean x = false;

    Ang operator ng karagdagan ( +), halimbawa, ay may mas mataas na precedence kaysa sa operator ng paghahambing !=("hindi katumbas");

    Samakatuwid sa expression:

    boolean x = 7 != 6+1;

    una ang operasyon 6+1 ay isasagawa, pagkatapos ay ang check 7!=7 (false), at sa dulo ang resulta ay itatalaga sa falsevariable x. Ang pagtatalaga sa pangkalahatan ay may pinakamababang priyoridad sa lahat ng mga operasyon - tingnan sa talahanayan.

Phew! Mahaba ang lecture natin, pero nagawa mo! Kung hindi mo lubos na nauunawaan ang ilang bahagi nito at ang mga nakaraang lektura, huwag mag-alala, tatalakayin namin ang mga paksang ito nang higit sa isang beses sa hinaharap. Narito ang ilang kapaki-pakinabang na link para sa iyo:
  • Logical Operators - JavaRush lecture sa mga lohikal na operasyon. Hindi namin sila mapupuntahan anumang oras sa lalong madaling panahon, ngunit maaari mong basahin ang mga ito ngayon, walang anumang pinsala
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION