DERS 35 - Bitwise Operatörleri

Bu eğitim videosunda bit seviyesinde nasıl işlem yapabiliriz konusu işleniyor. Bitwise operatörleri (Bitsel Operatörleri) kullanılarak örnek program yazılıyor.

Özetle bir değerin içindeki bit'ler ile çalışan operatörlere denir. & (and) , | (or) , ^ (xor) , ~ (not) bitwise operatörleridir. >> (right shift) , << (left shift) gibi bit shift operator'leri de bitwise operatörü olarak kabul edilir

Operatör Açıklama
& AND işlemi
| OR işlemi
^ XOR işlemi
~ NOT İşlemi, Pythonda ~x = -(x+1) işlemine denk geliyor
<< Sola kaydırma
>> Sağa kaydırma

& operatörü ile elinizdeki bir sayıyı başka bir sayı ile bit düzeyinde AND işlemine tabi tutabilirsiniz. Örnek kullanım aşağıdadır:

a = 3
# bit değeri: 0011

b = 5
# bit değeri: 0101

a &= b

#         0011
#(AND)    0101
#-------------
#         0001


print(a)    # 1

| operatörü ile elinizdeki bir sayıyı başka bir sayı ile bit düzeyinde OR işlemine tabi tutabilirsiniz. Örnek kullanım aşağıdadır:

a = 3
# bit değeri: 0011

b = 5
# bit değeri: 0101

a |= b

#         0011
#(OR)     0101
#-------------
#         0111


print(a)    # 7

^ operatörü ile elinizdeki bir sayıyı başka bir sayı ile bit düzeyinde XOR işlemine tabi tutabilirsiniz. Örnek kullanım aşağıdadır:

a = 3
# bit değeri: 0011

b = 5
# bit değeri: 0101

a ^= b

#          0011
#(XOR)     0101
#--------------
#          0110


print(a)    # 6

~ operatörü ile elinizdeki bir sayıyı ~x = -(x+1) işlemine tabi tutabilirsiniz. Örnek kullanım aşağıdadır:

a = 3
# bit değeri: 0011

a = ~a

#-(x+1)    0011
#--------------
#         -0100


print(a)    # -4

>> operatörü ile elinizdeki bir sayının bit değeri üzerinden sağa kaydırma işlemi yapabilirsiniz. Soldan gelen yeni bitle ise 0 değerini alır. Örnek kullanım aşağıdadır:

a = 5
# bit değeri: 0101

a >>= 2
# yeni bit değeri: 0001

print(a)    #1

<< operatörü ile elinizdeki bir sayının bit değeri üzerinden sola kaydırma işlemi yapabilirsiniz. Sağdan gelen yeni bitle ise 0 değerini alır. Örnek kullanım aşağıdadır:

a = 13
# bit değeri: 1101

a <<= 5
# yeni bit değeri: 110100000

print(a)    #416

Bit maskeleri

Bit maskesi, boyanın bir yüzeyin belirli alanlarına püskürtülmesini engelleyen bir grafiti kalıbı gibi çalışır. Seçici olarak üzerlerine bazı işlevler uygulamak için bitleri izole etmenizi sağlar. Bit maskesi oluşturma, hem bitsel mantıksal işleçleri hem de hakkında okuduğunuz bitsel kaydırma işleçlerini içerir.

Bit maskelerini birçok farklı bağlamda bulabilirsiniz. Örneğin, IP adreslemedeki alt ağ maskesi aslında ağ adresini çıkarmanıza yardımcı olan bir bit maskesidir. RGB modelinde kırmızı, yeşil ve mavi renklere karşılık gelen piksel kanallarına bir bit maskesi ile erişilebilir. Daha sonra bir bit alanına paketleyebileceğiniz Boole bayraklarını tanımlamak için bir bit maskesi de kullanabilirsiniz.

Bit maskeleriyle ilişkili birkaç yaygın işlem türü vardır. Aşağıda bunlardan bazılarına hızlıca göz atacaksınız.

Daha Fazla Detay

Belirli bir konumdaki belirli bir bitin değerini okumak için, istenen dizinde yalnızca bir bitten oluşan bir bit maskesine karşı bitsel AND'i kullanabilirsiniz:

def get_bit(value, bit_index):
    return value & (1 << bit_index)

my_val = get_bit(0b10000000, bit_index=5)
print(my_val)   #0
my_val = get_bit(0b10100000, bit_index=5)
print(my_val)   #32

Maske, ilgilendiğiniz hariç tüm bitleri bastıracaktır. Bu, ya sıfır ya da ikinin üssü, bit indeksine eşit bir üs ile sonuçlanacaktır. Bunun yerine basit bir evet-hayır cevabı almak istiyorsanız, sağa kayabilir ve en az önemli olan kısmı kontrol edebilirsiniz:

def get_normalized_bit(value, bit_index):
    return (value >> bit_index) & 1

my_val = get_normalized_bit(0b10000000, bit_index=5)
print(my_val)   #0
my_val = get_normalized_bit(0b10100000, bit_index=5)
print(my_val)   #1

Bu sefer, bit değerini normalleştirecek, böylece asla 1'i geçmeyecek. Daha sonra bu işlevi sayısal bir değer yerine bir Boolean True veya False değeri türetmek için kullanabilirsiniz.

Bir Bit Ayarlama

Biraz ayarlamak, bir tane almaya benzer. Öncekiyle aynı bit maskesinden yararlanırsınız, ancak bitsel AND kullanmak yerine bitsel OR operatörünü kullanırsınız:

def set_bit(value, bit_index):
    return value | (1 << bit_index)

my_val = set_bit(0b10000000, bit_index=5)
print(my_val)       #160
print(bin(my_val))      #'0b10100000'

Maske, belirtilen dizinde bir ikili olanı uygularken tüm orijinal bitleri korur. Bu bit zaten ayarlanmış olsaydı, değeri değişmezdi.

Bir Biti Temizlemek (Sıfır Yapmak)

Bir biti temizlemek için, belirli bir dizinde sıfırı zorlarken tüm ikili basamakları kopyalamak istiyorsunuz. Bu etkiyi, aynı bit maskesini bir kez daha, ancak tersine çevrilmiş biçimde kullanarak elde edebilirsiniz:

def clear_bit(value, bit_index):
    return value & ~(1 << bit_index)

my_val = clear_bit(0b11111111, bit_index=5)
print(my_val)           #223
print(bin(my_val))      #'0b11011111'

Bir pozitif sayı üzerinde bitsel NOT kullanmak Python'da her zaman negatif bir değer üretir. Bu genellikle istenmeyen bir durum olmakla birlikte, burada önemli değildir çünkü hemen bitsel AND işlecini uygularsınız. Bu da, maskenin ikinin tamamlayıcı gösterimine dönüşümünü tetikleyerek size beklenen sonucu verir.

Bir Bit Değiştirmek (Toggling)

Bazen periyodik olarak biraz açıp kapatmak yararlı olabilir. Bu, bitsel XOR operatörü için mükemmel bir fırsattır ve sizin parçanızı şu şekilde çevirebilir:

def toggle_bit(value, bit_index):
    return value ^ (1 << bit_index)

x = 0b10100000
for _ in range(5):
    x = toggle_bit(x, bit_index=7)
    print(bin(x))

# Terminal Çıktısı
# 0b100000
# 0b10100000
# 0b100000
# 0b10100000
# 0b100000

Aynı bit maskesinin yeniden kullanıldığına dikkat edin. Belirtilen konumdaki bir ikili, bu dizindeki biti değerini tersine çevirecektir. Kalan yerlerde ikili sıfırların olması, kalan bitlerin kopyalanmasını sağlayacaktır.


DERSLER