Ders 05 / 16
Bit Düzeyi İşlemler
VE, VEYA, XOR, DEĞİL işleçleri, kaydırmalar ve maskeleme ile alan ayıklama.
İçindekiler
Önceki dersler bit örüntülerini hep bir bütün olarak yorumladı: otuz iki bit birlikte bir tam sayı ya da bir gerçel sayı oluşturuyordu. Programlar ise sık sık örüntünün parçalarıyla çalışır — tek bir baytı ayıklamak, bir bayrağı açmak, bir alanı sıfırlamak gibi.
Bu dersin konusu, bu parça işlemlerini yapan işleçlerdir. Bunlar donanımın en ucuz işlemleri arasındadır ve düşük seviyeli kodun büyük bölümü bunlarla yazılır.
Mantıksal İşleçler
Dört temel işleç, bitler üzerinde tanımlı doğruluk tablolarıyla verilir. İşleçler bit bit uygulanır: sonucun ’nci biti, girdilerin yalnızca ’nci bitlerine bağlıdır.
| (VE) | (VEYA) | (XOR) | ||
|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 |
| 0 | 1 | 0 | 1 | 1 |
| 1 | 0 | 0 | 1 | 1 |
| 1 | 1 | 1 | 1 | 0 |
DEĞİL işleci tek girdilidir ve her biti ters çevirir: , .
Sekiz bitlik iki örüntü üzerinde:
1100 1010 1100 1010 1100 1010 & 1010 0110 | 1010 0110 ^ 1010 0110 ----------- ----------- ----------- 1000 0010 1110 1110 0110 1100
Her işlecin ayırt edici bir kullanımı vardır:
- VE, istenmeyen bitleri sıfırlar: karşısında olan her bit silinir.
- VEYA, istenen bitleri açar: karşısında olan her bit kurulur.
- XOR, seçili bitleri ters çevirir; ayrıca “farklı mı?” sorusunun bit karşılığıdır. Bir sayının kendisiyle XOR’u sıfırdır, bu da aynı değerle iki kez XOR yapmanın başlangıç değerine döndüğü anlamına gelir.
Bu işleçlerin mantıksal ve/veya işleçleriyle karıştırılmaması gerekir. Mantıksal
işleçler tüm değeri doğru/yanlış olarak ele alır ve çoğu dilde kısa devre yapar; bit
düzeyi işleçler her biti bağımsız işler ve kısa devre yapmaz.
Kaydırma
Sola kaydırma (<<) tüm bitleri sola taşır, sağdan sıfır doldurur. Her kaydırma,
konum değerlerini iki katına çıkardığı için sayıyı ikiyle çarpar:
Sağa kaydırma (>>) bitleri sağa taşır ve sayıyı ikiye böler; kesirli kısım atılır.
Soldan hangi bitin dolduğu, değerin yorumuna bağlıdır:
- Mantıksal kaydırma soldan sıfır doldurur; işaretsiz değerler için doğrudur.
- Aritmetik kaydırma soldan işaret bitinin kopyasını doldurur; işaretli değerlerin işaretini korur.
Bu ayrım, önceki dersteki işaret genişletme kuralının aynısıdır. Python’da tam sayılar
işaretlidir ve >> aritmetik davranır: -8 >> 1 sonucu -4, -5 >> 1 sonucu -3’tür
(sonuç sıfıra değil, aşağı yuvarlanır).
Sabit genişlikli dillerde kaydırma sayısının veri genişliğine eşit veya daha büyük olması tanımsız davranıştır; 32 bitlik bir değeri 32 kez kaydırmak taşınabilir bir sonuç vermez. Bu, sessizce yanlış çalışan kodun bilinen kaynaklarından biridir.
Maskeleme
Maske, hangi bitlerle ilgilenildiğini belirten sabit bir örüntüdür. Dört temel işlem maskeyle yapılır:
| Amaç | İşlem | Açıklama |
|---|---|---|
| Bit sınama | deger & maske |
Sonuç sıfır değilse ilgili bit kuruludur |
| Bit kurma | deger | maske |
Maskede olan bitler açılır |
| Bit silme | deger & ~maske |
Maskede olan bitler sıfırlanır |
| Bit ters çevirme | deger ^ maske |
Maskede olan bitler ters çevrilir |
Bir alanı ayıklamak iki adımdır: alanı en sağa kaydır, sonra fazlasını maskele. Kursun ortak örneğinden ikinci baytı almak için:
Kaydırma miktarı, alanın sağdan kaç bit uzakta başladığını; maske ise alanın kaç bit
genişliğinde olduğunu söyler. 0xFF sekiz bitlik, 0x0F dört bitlik, 0x01 tek bitlik
bir alan seçer.
Aynı yöntem tersinden de çalışır: bir alana değer yazmak için önce alan silinir, sonra yeni değer kaydırılıp VEYA ile yerleştirilir.
Bayrak Kümeleri
Birbirinden bağımsız açık/kapalı seçeneklerin her biri bir bite atanabilir. Bu düzen, tek bir tam sayıda çok sayıda seçeneği taşır ve seçeneklerin birleştirilmesini, sınanmasını ucuz kılar.
OKUMA = 0b100 # 4 YAZMA = 0b010 # 2 CALISMA = 0b001 # 1 izin = OKUMA | YAZMA # 0b110 = 6 print(bool(izin & YAZMA)) # True — yazma izni var mı? print(bool(izin & CALISMA)) # False izin |= CALISMA # çalışma iznini ekle -> 0b111 izin &= ~YAZMA # yazma iznini kaldır -> 0b101 print(f"{izin:03b}") # 101
Bu örnekteki üç bit, ikinci derste sekizlik gösterimle yazılan dosya izinlerinin ta
kendisidir: 0b101 örüntüsü 5, yani r-x iznidir. Sekizlik gösterimin o alanda
tercih edilmesinin nedeni, üçlü bit gruplarının doğrudan tek rakama karşılık gelmesiydi.
Yaygın Deyimler
Bit işleçleriyle kurulan birkaç kalıp, kaynak kodda sık görülür:
x & (x - 1)— en sağdaki kurulu biti siler. Sonuç sıfırsa ikinin kuvvetidir (yalnız bir biti kuruluydu). Aynı ifade döngüde kullanılarak kurulu bitler sayılır.x & -x— yalnızca en sağdaki kurulu biti bırakır. İkiye tümleyende negatif alma işleminin tanımından çıkar.x << kvex >> k— ikinin kuvvetleriyle çarpma ve bölme. Derleyiciler bu dönüşümü zaten yapar; kaynakta kaydırma yazmak okunabilirliği düşürür ve başarım kazandırmaz.x ^ maske— seçili bitleri ters çevirme;x ^ xher zaman sıfırdır.
Aşağıdaki program, bu deyimlerin ikisini ve alan ayıklamayı bir arada gösterir:
def ikinin_kuvveti_mi(x: int) -> bool: """Pozitif x, tam olarak bir bit kuruluysa ikinin kuvvetidir.""" return x > 0 and (x & (x - 1)) == 0 def kurulu_bit_sayisi(x: int) -> int: """Her adımda en sağdaki kurulu biti silerek sayar.""" sayac = 0 while x: x &= x - 1 sayac += 1 return sayac deger = 0x41424344 baytlar = [(deger >> k) & 0xFF for k in (24, 16, 8, 0)] print([hex(b) for b in baytlar]) # ['0x41', '0x42', '0x43', '0x44'] print(ikinin_kuvveti_mi(64)) # True print(ikinin_kuvveti_mi(48)) # False print(kurulu_bit_sayisi(deger)) # 9 print(bin(deger).count("1")) # 9 — aynı sonuç, farklı yol
kurulu_bit_sayisi işlevinin döngüsü, kurulu bit sayısı kadar döner; bit genişliği
kadar değil. 0x41424344 örüntüsünde dokuz bit kuruludur (0x41 ve 0x42 ikişer,
0x43 üç, 0x44 iki), dolayısıyla döngü otuz iki değil dokuz kez çalışır.
Özet
- Bit düzeyi işleçler her biti bağımsız işler; mantıksal işleçlerden farklı olarak değerin tamamını doğru/yanlış olarak ele almazlar.
- VE bit siler, VEYA bit kurar, XOR bit ters çevirir; bir değerin kendisiyle XOR’u sıfırdır.
- Sola kaydırma ikiyle çarpar; sağa kaydırma ikiye böler ve soldan doldurma kuralı değerin işaretli yorumlanıp yorumlanmadığına bağlıdır.
- Alan ayıklama iki adımdır: alanı sağa kaydır, ardından genişliği kadar maske uygula.
- Bağımsız seçenekler tek bir tam sayıda bayrak bitleri olarak taşınabilir; birleştirme VEYA, sınama VE ile yapılır.
x & (x - 1)en sağdaki kurulu biti siler; ikinin kuvveti sınaması ve bit sayımı bu deyime dayanır.
Sonraki Adım
Sayılar için temsil kuralları tamamlandı. Metin ise farklı bir sorun çıkarır: harfler doğal olarak sayı değildir; her karakterin bir sayıya eşlenmesi gerekir ve bu eşleme üzerinde dünya çapında anlaşmak gerekir. Sonraki ders, bu anlaşmanın nasıl kurulduğunu ve kod noktası ile bayt dizisi arasındaki farkın neden önemli olduğunu ele alacak.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.