---
title: 'Bit Düzeyi İşlemler'
source: 'https://academia.sh/tr/kurslar/bilgisayarlar-nasil-calisir/bit-duzeyi-islemler'
course: 'Bilgisayarlar Nasıl Çalışır'
language: tr
updated: '2026-08-17T18:08:08+00:00'
license: 'CC BY-SA 4.0'
---

# Bit Düzeyi İşlemler

VE, VEYA, XOR, DEĞİL işleçleri, kaydırmalar ve maskeleme ile alan ayıklama.

Ö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 $i$'nci biti, girdilerin yalnızca $i$'nci bitlerine bağlıdır.

| $a$ | $b$ | $a \mathbin{\&} b$ (VE) | $a \mid b$ (VEYA) | $a \oplus b$ (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: $\lnot 0 = 1$, $\lnot 1 = 0$.

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 $0$ olan her bit silinir.
- **VEYA**, istenen bitleri açar: karşısında $1$ 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:

$$
\texttt{0000 0101} \ll 2 = \texttt{0001 0100} \qquad (5 \times 4 = 20)
$$

**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 $1$ olan bitler açılır |
| Bit silme | `deger & ~maske` | Maskede $1$ olan bitler sıfırlanır |
| Bit ters çevirme | `deger ^ maske` | Maskede $1$ 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:

$$
(\texttt{0x41424344} \gg 16)\ \&\ \texttt{0xFF} = \texttt{0x42}
$$

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.

```python
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 $x$ 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 << k` ve `x >> 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 ^ x` her zaman sıfırdır.

Aşağıdaki program, bu deyimlerin ikisini ve alan ayıklamayı bir arada gösterir:

```python
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.
