CodeGym /Java Blogu /Rastgele /Java Bitsel operatörler
John Squirrels
Seviye
San Francisco

Java Bitsel operatörler

grupta yayınlandı
Bugünün dersinde, Java Bitwise Operatörlerini tanıyacağız ve onlarla nasıl çalışılacağına dair örnekleri ele alacağız. Muhtemelen "bit" kelimesini biliyorsunuzdur. Değilse ne anlama geldiğini hatırlayalım :) Bit, bilgisayardaki en küçük bilgi birimidir. Adı ikili basamaktan gelir . Bir bit, iki sayıdan biriyle ifade edilebilir: 1 veya 0. Birler ve sıfırlara dayalı özel bir ikili sayı sistemi vardır. Burada matematiksel bir ormana girmeyeceğiz. Yalnızca Java'daki herhangi bir sayının ikili biçime dönüştürülebileceğini not edeceğiz. Bunu yapmak için sarmalayıcı sınıflarını kullanmanız gerekir.
Bitsel operatörler - 1
Örneğin, int için bunu şu şekilde yapabilirsiniz :

public class Main {

   public static void main(String[] args) {

       int x = 342;
       System.out.println(Integer.toBinaryString(x));
   }
}
Konsol çıktısı: 101010110 1010 10110 (okunmasını kolaylaştırmak için boşluk ekledim) ondalık sistemde 342 sayısıdır. Aslında bu sayıyı ayrı bitlere ayırdık: sıfırlar ve birler. Bitler üzerinde yapılan işlemlere bitwise denir .
  • ~ - bit düzeyinde DEĞİL.
Bu operatör çok basittir: numaramızın her bir bitinin üzerinden geçer ve biti çevirir: sıfırlar bir olur ve birler sıfır olur. 342 sayımıza uygularsak şöyle olur: 101010110 342 ikili sayı olarak temsil edilir 010101001 ~342 ifadesinin değeridir Bunu uygulamaya çalışalım:

public class Main {

   public static void main(String[] args) {

       int x = 342;
       System.out.println(~x);
   }
}
Konsol çıktısı: 169 169 , tanıdık ondalık sistemdeki sonucumuzdur ( 010101001 ) :)
  • & - bit düzeyinde VE
Gördüğünüz gibi mantıksal AND'e ( && ) oldukça benziyor. Hatırlayacağınız üzere && işleci , yalnızca her iki işlenen de doğruysa doğru döndürür. Bitwise & benzer şekilde çalışır: iki sayıyı bit parça karşılaştırır. Karşılaştırma üçüncü bir sayı üretir. Örneğin, 277 ve 432 sayılarını ele alalım: 110110000, ikili sayı olarak temsil edilen 277'dir 1000101011, ikili sayı olarak temsil edilen 432'dir . Bu bir AND işleci olduğundan, yalnızca her iki bit de 1 ise sonuç 1 olur. Diğer durumlarda sonuç 0'dır. 100010101 && işleci Önce, iki sayının ilk bitlerini karşılaştırırız, sonra ikinci bitleri, sonra üçüncüyü vb. Gördüğünüz gibi, yalnızca iki durumda, sayıların her ikisi de 1'e (birinci ve beşinci bitler) eşit olan bitlere karşılık gelir. Diğer tüm karşılaştırmalar 0'lar üretti. Böylece sonunda 10001000 sayısını elde ettik. Ondalık sistemde 272 sayısına karşılık gelir. Kontrol edelim:

public class Main {

   public static void main(String[] args) {
       System.out.println(277&432);
   }
}
Konsol çıkışı: 272
  • | - bit düzeyinde VEYA.
Bu operatör aynı şekilde çalışır: iki sayıyı parça parça karşılaştırır. Ancak şimdi bitlerden en az biri 1 ise sonuç 1'dir. Aynı sayılara (277 ve 432) bakalım: 100010101 | 110110000 _______________ 110110101 - sonucu | operatör Burada farklı bir sonuç elde ediyoruz: sıfır olarak kalan bitler, her iki sayıda da sıfır olan bitlerdir. Sonuç 110110101 sayısıdır. Ondalık sistemde 437 sayısına karşılık gelir Kontrol edelim:

public class Main {

   public static void main(String[] args) {
       System.out.println(277|432);
   }
}
Konsol çıktısı: 437 Her şeyi doğru hesapladık! :)
  • ^ - bit düzeyinde XOR (özel VEYA)
Bu operatörle henüz karşılaşmadık. Ama bunda karmaşık bir şey yok. Sıradan OR operatörüne benzer. Bir fark vardır: en az bir işlenen doğruysa, sıradan VEYA doğru döndürür. Ancak bir olması gerekmez: her iki işlenen de doğruysa, sonuç da doğrudur. Ancak dışlayıcı OR, yalnızca işlenenlerden tam olarak biri doğruysa doğru döndürür. Her iki işlenen de doğruysa, sıradan OR doğru ("en az bir doğru") döndürür, ancak XOR yanlış döndürür. Bu yüzden özel OR denir. Önceki bitsel operatörlerin nasıl çalıştığını bildiğiniz için 277 ^ 432'yi kolayca hesaplayabilirsiniz. Ama bir kez daha birlikte inceleyelim :)operatör Bu bizim sonucumuz. Her iki sayıda da aynı olan bitler 0 üretir ("yalnızca bir" testin başarısız olduğu anlamına gelir). Ancak 0-1 veya 1-0 çifti oluşturan bitler bir oldu. Sonucumuz 010100101 sayısıdır. Ondalık sistemde 165 sayısına karşılık gelir. Bakalım hesaplarımız doğru mu:

public class Main {

   public static void main(String[] args) {
       System.out.println(277^432);
   }
}
Konsol çıkışı: 165 Süper! Her şey tam düşündüğümüz gibi :) Şimdi bit kaydırma operatörleri ile tanışma zamanı. Adı kendisi için konuşur. Bir sayı alıyoruz ve bitlerini sola veya sağa hareket ettiriyoruz :) Bakalım nasıl görünüyor:

Sola kay

Bitlerin sola kayması << ile gösterilir . İşte bir örnek:

public class Main {

   public static void main(String[] args) {
       int x = 64;//value
       int y = 3;// Shift distance

       int z = (x << y);
       System.out.println(Integer.toBinaryString(x));
       System.out.println(Integer.toBinaryString(z));
   }
}
Bu örnekte, x = 64 sayısına değer denir. Kaydıracağımız değerin bitleridir. Bitleri sola kaydıracağız ( << operatörünün yönünden bunu tahmin etmişsinizdir ) Binary sistemde 64=1000000 sayısı y=3 sayısına kaydırma mesafesi denir. Kaydırma mesafesi, x sayısının bitlerini kaç bit sağa/sola kaydırmak istediğinizi gösterir. Örneğimizde, bunları 3 bit sola kaydıracağız. Geçiş sürecini daha net görmek için resme bakın. Bu örnekte int s kullanıyoruz. Int'ler bilgisayarın belleğinde 32 bit yer kaplar. Orijinal 64 numaramız böyle görünüyor:
Bitsel operatörler - 2
Ve şimdi her bir parçamızı alıp kelimenin tam anlamıyla 3 basamak sola kaydırıyoruz:
Bitsel operatörler - 3
Elimize geçenlere bir göz atın. Gördüğünüz gibi, tüm bitlerimiz değişti ve aralığın kenarından 3 sıfır daha eklendi. Üç, çünkü 3 kaydırdık. 10 kaydırsaydık 10 sıfır eklenmiş olacaktı. Bu nedenle, x << y ifadesi " x sayısının bitlerini y basamak sola kaydır" anlamına gelir. İfademizin sonucu ondalık sistemde 512 olan 1000000000 sayısıdır. Hadi kontrol edelim:

public class Main {

   public static void main(String[] args) {
       int x = 64;//value
       int y = 3;// Shift distance

       int z = (x << y);
       System.out.println(z);
   }
}
Konsol çıkışı: 512 Spot on! Teorik olarak, bitler sonsuza kadar kaydırılabilir, ancak sayımız bir int olduğu için yalnızca 32 ikili basamağımız var. Bunlardan 7'si halihazırda 64 (1000000) tarafından işgal edilmiştir. Bu nedenle, 27 basamak sola kaydırırsak, yalnızca bir tanemiz veri türünün aralığının dışına çıkar ve kaybolur. Sadece sıfırlar kalacaktı!

public class Main {

   public static void main(String[] args) {
       int x = 64;//value
       int y = 26;// Shift distance

       int z = (x << y);
       System.out.println(z);
   }
}
Konsol çıktısı: 0 Beklendiği gibi, bir mevcut 32 bitin ötesine geçti ve kayboldu. Sadece sıfırlardan oluşan 32 bitlik bir sayı ile bitirdik.
Bitsel operatörler - 4
Doğal olarak bu ondalık sistemde 0'a karşılık gelir. Sola kaymaları hatırlamak için basit bir kural: Sola her kaydırma için sayı 2 ile çarpılır. 111111111 << 3 bitlerinin resimleri olmadan aşağıdaki ifadeyi hesaplamaya çalışalım 111111111 sayısını 2 ile çarpmamız gerekiyor . Sonuç olarak 888888888 elde ederiz. Biraz kod yazıp kontrol edelim:

public class Main {

   public static void main(String[] args) {
       System.out.println(111111111 << 3);
   }
}
Konsol çıkışı: 888888888

Sağa kaydır

Bu işlem >> ile gösterilir . Aynı şeyi yapar, ama diğer yönde! :) Tekerleği yeniden icat etmeyeceğiz. Aynı int 64 ile deneyelim .

public class Main {

   public static void main(String[] args) {
       int x = 64;//value
       int y = 2;// Shift distance

       int z = (x >> y);
       System.out.println(z);
   }
}
Bitsel operatörler - 5
Bitsel operatörler - 6
Sağa 2'lik bir kaydırma sonucunda, sayımızdaki iki uç sıfır aralığın dışına çıkar ve kaybolur. Ondalık sistemdeki 16 sayısına karşılık gelen 10000'i elde ederiz. Konsol çıktısı: 16 Sağa kaydırmaları hatırlamak için basit bir kural: Sağa her kaydırma ikiye bölünür ve kalanlar atılır. Örneğin, 35 >> 2, 35'i iki kez 2'ye bölmemiz gerektiği anlamına gelir, kalanları atarız 35/2 = 17 (kalan 1'i atın) 17/2 = 8 (kalan 1'i atın) Sonunda, 35 >> 2 8'e eşit olsun. Kontrol edelim:

public class Main {

   public static void main(String[] args) {
       System.out.println(35 >> 2);
   }
}
Konsol çıkışı: 8

Java'da operatör önceliği

Kod yazarken ve okurken, genellikle birkaç işlemi birleştiren ifadeler bulacaksınız. Çalıştırılacakları sırayı anlamak çok önemlidir (aksi takdirde sonuca şaşırabilirsiniz) Java'da çok sayıda işlem olduğundan, her birine özel bir tabloda bir yer atanmıştır:

Operatör Önceliği

Operatörler Öncelik
sonek ifade++ ifade--
tekli ++ifade --ifade +ifade ~ !
Çarpımsal * / %
katkı + -
vardiya << >> >>>
ilişkisel < > <= >= örnek
eşitlik == !=
bitsel VE &
bit düzeyinde özel VEYA ^
bitsel kapsayıcı VEYA |
mantıksal VE &&
mantıksal VEYA ||
üçlü ? :
atama = += -= *= /= %= &= ^= |= <<= >>= >>>=
Tüm işlemler, öncelikleri dikkate alınarak soldan sağa doğru gerçekleştirilir. Örneğin, yazarsak

int x  = 6 - 4/2;
daha sonra bölme işlemi ( 4/2 ) ilk olarak gerçekleştirilecektir. İkinci sırada olmasına rağmen, daha yüksek önceliğe sahiptir. Parantezler ve parantezler maksimum önceliği gösterir. Muhtemelen bunu okuldan hatırlıyorsundur. Örneğin, bunları ifadeye eklerseniz

int x  = (6 - 4)/2;
parantez içinde olduğu için önce çıkarma işlemi yapılır. Mantıksal && işlecinin önceliği oldukça düşüktür (tabloya bakın), bu nedenle genellikle sonuncu olur. Örneğin:

boolean x = 6 - 4/2 > 3 && 12*12 <= 119;
Bu ifade şu şekilde yürütülecektir:
  • 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;
Ardından, karşılaştırma işleçleri yürütülür:
  • 4 > 3 = doğru

boolean x = true && 144 <= 119;
  • 144 <= 119 = yanlış

boolean x = true && false;
Ve son olarak, AND işleci ( && ) en son yürütülür.

boolean x = true && false;
boolean x = false;
Örneğin, toplama( + ) işleci != (eşit değil) karşılaştırma işlecinden daha yüksek önceliğe sahiptir ; Bu nedenle, ifadede

boolean x = 7 != 6+1;
önce 6+1 işlemi gerçekleştirilecek, ardından 7 != 7 kontrolü (yanlış olarak değerlendirilir) ve son olarak sonucun (yanlış) x değişkenine atanması (atama genellikle tüm operatörler arasında en düşük önceliğe sahiptir; bkz . tablo). Vay! Bu büyük bir dersti ama başardın! Bu veya önceki derslerin bazılarını tam olarak anlamadıysanız endişelenmeyin. İleride bu konulara birden çok kez değineceğiz. Mantıksal ve sayısal işlemler hakkında birkaç CodeGym dersi. Bunlara yakın zamanda değinmeyeceğiz ama onları şimdi okumanızda bir sakınca yok.
Yorumlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION