Skip to content
Bloga Dönün
Eğitimler

Bitwise İşlemler: AND, OR, XOR, Kaydırmalar ve Maskeler

Bitwise işlemleri uygulamalı örneklerle öğrenin: AND, OR, XOR, kaydırmalar, ikinin tümleyeni, bit maskeleri ve özellik bayrakları — JS, Python, Go ve C kodlarıyla.

17 dakika okuma

Pratikte Bitwise İşlemler: AND, OR, XOR, Kaydırmalar, Maskeler

Eski bir PostgreSQL şema taşıma dosyasını açarsınız ve permissions & 0b100 ifadesini görürsünüz. Bir meslektaşınız 32 booleanı tek bir tam sayıya paketleyen bir özellik bayrağı sistemi yayımlar. Bir Kubernetes alt ağ hesabı 192.168.1.0/24 çıktısı verir ve ağ adresini kodda çıkarmanız gerekir. Üç durum, altta yatan tek bir beceri: bitwise işlemler.

Çoğu uygulama katmanı geliştiricisinin bir web uygulamasında & veya ^ operatörüne uzanması gerekmez — ta ki bir gün aniden gerekene kadar. Bu rehber altı bitwise operatörünü, ikinin tümleyenini, ezberlemeye değer dokuz deseni ve sizi yakalayacak dile özgü tuzakları (özellikle JavaScript’te) adım adım ele alır. Kod JS, Python, Go ve C dillerindedir; her örnek çalıştırılabilir.

Sayı Tabanı Dönüştürücü aracımızı başka bir sekmede açın. Birkaç bölüm sizi bir sayı yazıp bit deseninin değişimini izlemeye davet ediyor.

2026’da bitwise işlemler neden hâlâ önemli

Yüksek seviyeli diller bitwise işlemleri eskimiş hâle getirmedi. Yalnızca bu işlemlerin nerede gerçekleştiğini gizlediler. Bugün farkında olun ya da olmayın bunlara dayandığınız birkaç yer:

  • PostgreSQL satır düzeyi güvenlik, bir tam sayıya paketlenmiş ACL ayrıcalıklarının (SELECT, INSERT, UPDATE, DELETE, …) bit eşlemini kullanır.
  • Linux yetenekleri, eski “ya root ya da hiç” modelini | ile birleştirdiğiniz 40+ izin biti ile değiştirir.
  • JWT algoritma header’leri, kütüphane katmanında bit düzeyinde karşılaştırmanın yaygın olduğu küçük bir alanda özet algoritmasını kodlar.
  • Snowflake, ULID ve UUIDv7; sola kaydırma kullanarak zaman damgasını, makine kimliğini ve sıra numarasını tek bir 64 bit veya 128 bit tam sayıya paketler.
  • Redis BITCOUNT ve BITOP; kardinalite tahmini ve A/B gruplama için bitwise temel işlemlerini doğrudan uygulama koduna sunar.
  • Görüntü işleme, 32 bit RGBA piksellerini okur ve & ile >> kullanarak kanalları çıkarır.

Bitwise işlemler CPU komut düzeyinde O(1) olmayı sürdürür. 32 booleanı tek bir tam sayıya paketlediğinizde 31 bayt bellek kazanırsınız ve (daha da önemlisi) “bu 32 bayraktan herhangi biri ayarlı mı” sorgusunu tek bir != 0 testiyle yapabilirsiniz.

Önce gereken ikilik temeller

Bu rehber, ikilik sistemin nasıl çalıştığını zaten bildiğinizi varsayar. Hatırlamaya ihtiyacınız varsa önce Sayı Tabanı Dönüşümü Rehberi yazımızı okuyun ve geri dönün.

Başlamadan önce hızlı bir söz dağarcığı kontrolü:

  • Bir bit, 0 veya 1’dir.
  • Bir nibble, 4 bittir (bir hex basamağı).
  • Bir bayt, 8 bittir.
  • Bir kelime (word) genellikle CPU’nuza bağlı olarak 32 veya 64 bittir.

Çoğu dilde tam sayılar sabit genişliklerde gelir: 8, 16, 32, 64. Genişlik bitwise işlemler için çok önemlidir, çünkü kaydırmalar bitleri uçtan dışarı itebilir ve işaret biti, işaretli tam sayıların en sol konumunda yer alır.

Şunu hemen deneyin. Sayı Tabanı Dönüştürücü aracını açın, ondalık olarak 170 girin ve ikilik çıktıya bakın. 10101010 görmelisiniz — aşağıda birkaç kez geri döneceğimiz dönüşümlü bir desen.

Altı bitwise operatörü

Tüm yaygın diller size aynı altı operatörü, kimi zaman küçük söz dizimi farklarıyla sunar. &, |, ^, ~, <<, >> sembolleri JavaScript, Python, Go, Rust, C, C++, Java ve C# dillerinde değişmeden çalışır. JavaScript bir tane daha ekler: >>>, işaretsiz sağa kaydırma.

AND (&): bit filtresi

Çıkış biti yalnızca her iki giriş biti de 1 ise 1 olur.

ABA & B
000
010
100
111

AND’i bir geçit gibi düşünün: yalnızca her iki operandda da ayarlı olan bitler hayatta kalır. En yaygın kullanım maskelemedir — bazı bitleri tutmak ve diğerlerini sıfırlamak.

// Düşük 4 biti çıkar (en sağdaki nibble)
const value = 0b11010110;   // 214
const low4  = value & 0x0F; // 0b00000110 = 6

// Bir sayının tek olup olmadığını kontrol et
const isOdd = (n) => (n & 1) === 1;
isOdd(7);  // true
isOdd(42); // false
# Python'da aynısı
value = 0b11010110
low4 = value & 0x0F  # 6

def is_odd(n):
    return (n & 1) == 1

OR (|): bit ayarlayıcı

Çıkış biti, herhangi bir giriş biti 1 ise 1 olur.

ABA | B
000
011
101
111

OR bayrakları birleştirir. READ = 1, WRITE = 2, EXECUTE = 4 ise, READ | WRITE her iki izin etkin olarak 3’tür.

const READ  = 0b001;
const WRITE = 0b010;
const EXEC  = 0b100;

const rw = READ | WRITE;  // 0b011 = 3
READ, WRITE, EXEC = 0b001, 0b010, 0b100
rw = READ | WRITE  # 3

XOR (^): bit anahtarı

Çıkış biti, giriş bitleri farklı ise 1 olur.

ABA ^ B
000
011
101
110

XOR’un bilgisayar bilimindeki en zekice numaralardan bazılarını mümkün kılan üç cebirsel özelliği vardır:

  • a ^ a = 0: bir şey kendisiyle XOR’lanırsa iptal olur.
  • a ^ 0 = a: sıfırla XOR birim öğedir.
  • a ^ b ^ a = b: XOR kendi tersidir.

Son özellik, XOR’un parite kontrollerinde, akış şifrelerinde ve meşhur “bir dizide tekrarlanmayan tek sayıyı bul” mülakat sorusunda neden ortaya çıktığını açıklar.

// Her sayının iki kez tekrarlandığı bir dizide tek olan benzersiz sayıyı bul
const findUnique = (arr) => arr.reduce((a, b) => a ^ b, 0);
findUnique([4, 1, 2, 1, 2]);  // 4
from functools import reduce
from operator import xor
find_unique = lambda arr: reduce(xor, arr, 0)
find_unique([4, 1, 2, 1, 2])  # 4

NOT (~): bit tersleyici

Tekli ~ her biti çevirir: 0 olan 1, 1 olan 0 olur.

~0b00001111  // -16  (JavaScript 32 bit işaretliye dönüştürür)
~5           // -6
~5  # -6
// Go, tekli bitwise NOT için ^ kullanır, dikkat
var x int8 = 5
fmt.Println(^x)  // -6

~5 sonucu her yaygın dilde -6’dır ve bu yeni başlayanları şaşırtır. Sebep, bir sonraki bölümde ele aldığımız ikinin tümleyenidir. Şimdilik şunu bilin: ~x, negatifler için ikinin tümleyenini kullanan herhangi bir dilde -(x + 1) ifadesine eşittir (ki tüm modern diller bunu kullanır).

Sola kaydırma (<<): ikinin kuvvetiyle çarpıcı

x << n, x ifadesinin her bitini sola n konum kaydırır ve sağa sıfırlarla doldurur. Matematiksel olarak bu, 2ⁿ ile çarpmaktır.

1 << 0   // 1   (2^0)
1 << 1   // 2   (2^1)
1 << 3   // 8   (2^3)
1 << 10  // 1024 (2^10 = 1 KiB)

// Bit bayrakları oluşturma
const FLAG_ADMIN    = 1 << 0;
const FLAG_EDITOR   = 1 << 1;
const FLAG_REVIEWER = 1 << 2;

1 << n ifadesinin kullanışlı yanı, n konumunda yalnızca tek bir biti ayarlı olan bir sayı üretmesidir. Bu bit bir bayrak hâline gelir.

Taşmaya dikkat edin. JavaScript’te 1 << 31 sonucu -2147483648’dir (2147483648 değil), çünkü JavaScript bitwise operatörleri 32 bit işaretli tam sayılar üzerinde çalışır.

Sağa kaydırma (>> ile >>>): bölme mi, dolgulu mu?

Sağa kaydırma bitleri sağa taşır. Soru şu: boşalan en soldaki konumlara ne dolar?

  • >> (aritmetik sağa kaydırma) işaret bitini korur. Negatif sayılar negatif kalır.
  • >>> (mantıksal veya işaretsiz sağa kaydırma) sıfırlarla doldurur. Bunu özel bir operatör olarak yalnızca JavaScript barındırır.
-8 >> 1   // -4   (işaret biti korunur)
-8 >>> 1  // 2147483644  (işaret biti veri biti gibi ele alınır)

8 >> 1    // 4
8 >> 2    // 2

C’de >> operatörünün işaretli türler için aritmetik mi yoksa mantıksal mı olduğu uygulamaya bağlıdır. Çoğu derleyici aritmetik yapar, ancak kontrol etmeden buna güvenmeyin. Go, kaydırma miktarlarının işaretsiz tam sayılar olmasını gerektirir ve işaretli ile işaretsiz türleri açıkça ayırır. Python’da sabit genişlikli tam sayılar olmadığı için >>> yoktur.

İkinin tümleyeni: bilgisayarlar negatifleri nasıl temsil eder

Bitler yalnızca 0 ve 1 ise, -5 nasıl kodlanır? 1960’larda dünyanın üzerinde anlaştığı cevap, ikinin tümleyenidir ve her modern CPU bunu kullanır.

Saf yaklaşım (bir biti işaret için ayırmak) iki sorun doğurur. İlki, hem +0 hem de -0 ile karşılaşırsınız ki bu can sıkıcıdır. İkincisi, toplama ve çıkarma devrelerinin işaret bitini kontrol etmesi gerekir; bu da donanımı daha karmaşık hâle getirir. İkinin tümleyeni her ikisini de çözer.

Kural kısadır:

  1. Pozitif ikilik temsili al.
  2. Her biti çevir (bu “birin tümleyeni”dir).
  3. 1 ekle.

Çalışılmış örnek, -5’i 8 bit ikinin tümleyeniyle kodlama:

 5 ikilikte:         0000 0101
 tüm bitleri çevir:  1111 1010   (bu ikinin tümleyeninde -6'dır!)
 1 ekle:             1111 1011   ← bu -5'tir

Sayı tabanı dönüştürücümüzle doğrulayın: Sayı Tabanı Dönüştürücü aracına 251 (ondalık) girin, taban 10 seçin; ikilik çıktı 11111011 olur. 8 bit işaretli bağlamda 11111011, -5’tir. 8 bit işaretsiz bağlamda aynı bit deseni 251’dir. Bitler aynıdır; yorum farklıdır.

Bu, daha önceki ~5 = -6 sürprizini açıklar. Bitwise NOT bitleri çevirir; bu da size birin tümleyenini verir. İkinin tümleyeni ise birin tümleyeni artı 1’dir. Yani:

~x   = -(x + 1)        // ikinin tümleyenli her dilde özdeşlik
~5   = -6
~(-3) = 2

n bit işaretli tam sayılar için temsil edilebilir aralık -2ⁿ⁻¹’den 2ⁿ⁻¹ − 1’e kadardır. 8 bit işaretli bir tam sayı -128 ile 127 arasını kapsar. 32 bit işaretli bir tam sayı yaklaşık -2,1 milyar ile +2,1 milyar arasını kapsar.

Temel bit manipülasyonu desenleri

Bu dokuz desen, hayatınız boyunca yazacağınız bit manipülasyonunun belki de %95’ini kapsar. Bunları ezberleyin; sistem kodunda her yerde tanırsınız.

Bir biti ayarla: x | (1 << n)

n bitini aç, diğer bitleri olduğu gibi bırak.

let flags = 0b0100;
flags = flags | (1 << 0);  // 0b0101

Bir biti temizle: x & ~(1 << n)

n bitini kapat, diğer bitleri olduğu gibi bırak. ~(1 << n), yalnızca n biti hariç her biti ayarlı olan bir maskedir.

let flags = 0b0111;
flags = flags & ~(1 << 1);  // 0b0101

Bir biti tersle: x ^ (1 << n)

n bitini mevcut durumundan bağımsız olarak çevir.

let flags = 0b0100;
flags = flags ^ (1 << 2);  // 0b0000
flags = flags ^ (1 << 2);  // tekrar 0b0100

Bir biti kontrol et: (x >> n) & 1

n biti ayarlıysa 1, değilse 0 döndürür. Eşdeğer biçim: (x & (1 << n)) !== 0.

const flags = 0b0101;
const isBit2Set = (flags >> 2) & 1;  // 1

En düşük ayarlı biti yalıt: x & -x

x değerinin yalnızca en sağdaki 1 biti tutulan bir değer üretir. Numara işe yarar çünkü ikinin tümleyeninde -x, ~x + 1’dir; bu da en düşük ayarlı bit dahil her biti çevirir.

const x = 0b10110100;
const lowest = x & -x;  // 0b00000100 = 4

Bu, O(log n) prefix toplamlar için Fenwick ağaçlarının (Binary Indexed Trees) çekirdek numarasıdır.

Ayarlı bitleri say (popcount)

Bir tam sayıdaki 1 bitlerinin sayısını saymak. Çoğu dilin artık yerleşik bir işlevi vardır:

// JavaScript (BigInt veya elle)
const popcount = (n) => {
  let count = 0;
  while (n) { count += n & 1; n >>>= 1; }
  return count;
};
popcount(0b10110100);  // 4
# Python 3.10+
(0b10110100).bit_count()  # 4
// Go
import "math/bits"

bits.OnesCount(0b10110100) // 4

Geçici değişken olmadan XOR ile değiştirme

Klasik bir parti numarası: iki tam sayıyı üçüncü bir değişken olmadan değiştirmek. Bunu üretimde asla kullanmayın (geçici bir değişkenden daha yavaştır ve a ile b aynı bellek konumunu işaret ediyorsa bozulur), ama anlamaya değerdir.

let a = 5, b = 9;
a = a ^ b;  // a = 5 ^ 9
b = a ^ b;  // b = (5 ^ 9) ^ 9 = 5
a = a ^ b;  // a = (5 ^ 9) ^ 5 = 9
// a = 9, b = 5

İkinin kuvveti tespiti: (x & (x - 1)) === 0

İkinin bir kuvveti tam olarak tek bir biti ayarlıdır. 1 çıkarmak o biti kapatır ve daha düşük her biti ayarlar. AND’lemek yalnızca ikinin kuvvetleri (ve 0’ın kendisi, dolayısıyla x > 0 ile koruyun) için sıfır verir.

const isPow2 = (x) => x > 0 && (x & (x - 1)) === 0;
isPow2(16);  // true
isPow2(17);  // false

Hızlı tek/çift kontrolü: x & 1

Bazı dillerde x % 2’den hızlıdır, derleyici optimizasyonundan sonra diğerlerinde aynıdır. Kritik kod yollarında veya okunurluğun önemsiz olduğu yerlerde değerlidir.

const isOdd = (x) => (x & 1) === 1;

Gerçek kodda bit maskesi bayrakları

Yukarıdaki desenler her gün üretim kodunda karşımıza çıkar. İşte onlarla karşılaşacağınız dört yer.

32 booleanlık özellik bayrakları

32 alanlı bir boolean struct yerine onları tek bir tam sayıya paketleyin:

const FLAGS = {
  DARK_MODE:      1 << 0,
  NEW_NAV:        1 << 1,
  AI_SUGGESTIONS: 1 << 2,
  BETA_EDITOR:    1 << 3,
  // ... 1 << 31'e kadar
};

let userFlags = 0;
userFlags |= FLAGS.DARK_MODE | FLAGS.AI_SUGGESTIONS;  // dahil ol

if (userFlags & FLAGS.AI_SUGGESTIONS) {
  showSuggestions();
}

userFlags &= ~FLAGS.DARK_MODE;  // çık

Bu, 32 booleanı 4 bayta depolar ve herhangi bir altkümeyi tek bir AND ile sorgulamanıza imkân verir. Veritabanları bu deseni sever çünkü 32 sütun yerine tek bir sütundur.

Unix dosya izinleri

chmod 755 bitwise’dır. Üç sekizlik basamak, üçer bitlik üç gruba eşlenir:

7 = 111  (sahip:   rwx)
5 = 101  (grup:    r-x)
5 = 101  (diğer:   r-x)

Deneyin: Sayı Tabanı Dönüştürücü aracını açın, kaynağı sekizlik olarak ayarlayın, 755 girin ve ikilik çıktıya 111101101 olarak bakın. Dosya sistemi izin alanını tam olarak böyle saklar.

Yalnızca “grup yazma” iznini ekleme:

const perms = 0o755;
const withGroupWrite = perms | 0o020;  // 0o775

IP alt ağ maskeleme

192.168.1.10/24 verildiğinde, ağ adresini maskeyle AND’leyerek çıkarın:

const ip      = 0xC0A8010A;  // 192.168.1.10
const mask    = 0xFFFFFF00;  // 255.255.255.0 (/24)
const network = ip & mask;   // 0xC0A80100 = 192.168.1.0

Paketlenmiş kimlikler: Snowflake

Twitter’ın Snowflake’i; zaman damgasını, makine kimliğini ve sırayı 64 bit tam sayıya paketler:

┌─ 1 bit ─┬─── 41 bit ───┬─ 10 bit ─┬─ 12 bit ─┐
│ işaret  │ zaman damga. │  makine  │   sıra   │
└─────────┴──────────────┴──────────┴──────────┘

Bir kimlik kodlamak iki kaydırma ve iki OR’dur:

const id = (BigInt(timestamp) << 22n) |
           (BigInt(machineId) << 12n) |
            BigInt(sequence);

Çözmek tersidir: sağa kaydır ve maskele. Snowflake, ULID veya UUIDv7’yi ne zaman seçeceğinizin tam bir adım adım anlatımı için dağıtık kimlik karşılaştırması yazımıza bakın.

Dile özgü tuzaklar

JavaScript: 32 bit dönüşüm tuzağı

JavaScript, her bitwise işleminden önce operandları 32 bit işaretli tam sayılara dönüştürür ve sonucu tekrar bir Number’a çevirir. 2³¹ − 1 = 2147483647’nin üzerindeki herhangi bir değer taşar:

2147483647 | 0   // 2147483647   (hâlâ sorun yok)
2147483648 | 0   // -2147483648  (taştı!)
4294967295 | 0   // -1           (tüm bitler ayarlı, işaretli yorumlandı)

64 bit çalışma için BigInt kullanın. Genişlik sınırı olmayan bağımsız bitwise operatörleri vardır:

(2n ** 40n) | 1n  // 1099511627777n

Operatör önceliği hataları

Bu, gerçek dünyadaki en yaygın bitwise hatalarından biridir:

// Hatalı: == operatörü &'den daha sıkı bağlandığı için (x & (1 == 0)) olarak okunur
if (x & 1 == 0) { /* ... */ }

// Doğru: parantezleyin
if ((x & 1) == 0) { /* ... */ }

Karşılaştırma operatörleri C, JavaScript, Python, Go ve çoğu türevde bitwise AND/OR/XOR’dan daha sıkı bağlanır. Şüphe duyduğunuzda parantezleyin.

Dil karşılaştırma tablosu

DilGenişlik dönüşümüNegatif >>BigInt desteği
JavaScript32 bit işaretliye zorlar; >>> işaretsizaritmetikBigInt ayrı operatörleri vardır
PythonKeyfi hassasiyet; sabit genişlik yokaritmetikYerleşik
GoKatı; kaydırma miktarı işaretsiz olmalıişaretli türler için aritmetikmath/big
C/C++Türü takip eder; int, unsigned, vb.işaretliler için uygulamaya bağlıYerleşik yok
RustKatı; debug’da taşmada panic ederişaretli türler için aritmetiku128 / harici crate’ler

Python’un sonsuz genişlik bükümü

Python tam sayılarının sabit genişliği yoktur, dolayısıyla ikinin tümleyeni mantığı sola “sonsuza” uzanır. ~5 sonucunun (250 veya 65530 değil) -6 olmasının nedeni budur: Python sonucu sabit genişlikli bir bit deseni olarak değil, negatif bir tam sayı olarak ele alır. Sarma semantiğine ihtiyacınız varsa açıkça maskeleyin:

# 8 bit NOT'u taklit et
(~5) & 0xFF  # 250

2026’da performans gerçekliği

Yaygın inanış, bitwise işlemlerin “her zaman daha hızlı” olduğudur. 2026’da bu yarı doğrudur.

Derleyiciler bariz yeniden yazmaları zaten yapar. Modern optimize ediciler x * 2 ifadesini otomatik olarak x << 1’e dönüştürür. Hız için uygulama kodunda x << 1 yazmak, kargo kült performans ayarlamasıdır. Faydası yoktur, okunurluğa zarar verir.

Bitwise kodun gerçekten kazandığı yerler:

  • Sayısal koddaki kritik kod yolları: popcount, baştaki ve sondaki sıfır sayıları, bitboard satranç motorları.
  • Kompakt veri yapıları: Bloom filtreleri, roaring bitmap’ler, Fenwick ağaçları.
  • Donanım kayıtları ve belleğe eşlenmiş G/Ç: gömülü kod, çekirdekler, ürün yazılımı.
  • Şifreleme ilkelleri: AES, ChaCha20 ve SHA tamamen XOR, döndürme ve kaydırmalardan kuruludur.
  • Sıkıştırma ve açma: Huffman kodlaması, çalışma uzunluğu, paketlenmiş tam sayılar.
  • Veritabanı motorları: bit eşlem index’leri, Parquet sözlük kodlaması gibi paketlenmiş sütun biçimleri.

Yardımcı olmadığı yerler: istek başına iki kez çalışan bir iş mantığı işlevinde x % 2 ifadesini x & 1 ile değiştirmek. Hızlanma ölçülemez; okunurluk maliyeti gerçektir.

Bit manipülasyonunun her zaman kazandığı tek durum bellek ayak izidir. 32 bayrağı bir int içine paketlemek, 32 booleana göre 31 bayt kazandırır. Ölçekte (milyonlarca kullanıcı kaydı, milyarlarca olay), bu, önbellek dostu bir yerleşim ile L2’yi ezen bir iş yükü arasındaki farktır.

Hızlı başvuru hile sayfası

İşlemOperatörÖrnekSonuçTipik kullanım
AND&0b1100 & 0b10100b1000Bitleri maskele/çıkar
OR|0b1100 | 0b10100b1110Bayrakları birleştir
XOR^0b1100 ^ 0b10100b0110Tersle / fark tespit et
NOT~~0b1100...11110011Maske için tersle
Sola kaydırma<<1 << 382ⁿ ile çarp
Sağa kaydırma>>16 >> 242ⁿ ile böl (işaretli)
İşaretsiz sağa kaydırma (JS)>>>-1 >>> 04294967295İşaretsiz olarak ele al
Bit n ayarla|x | (1 << n)Biti aç
Bit n temizle& ~x & ~(1 << n)Biti kapat
Bit n tersle^x ^ (1 << n)Biti çevir
Bit n kontrol et&(x >> n) & 10 veya 1Biti test et
En düşük ayarlı bit& -x & -xBiti yalıt
2’nin kuvveti mi&x > 0 && (x & (x-1)) == 0boolKuvvet testi

SSS

Mantıksal (&&) ve bitwise (&) AND arasındaki fark nedir?

Mantıksal AND tüm boolean değerler üzerinde çalışır ve kısa devre yapar; dolayısıyla false && expr ifadesi expr’i hiçbir zaman değerlendirmez. Bitwise AND, tam sayıların tek tek bitleri üzerinde çalışır ve her zaman her iki tarafı değerlendirir. Koşullar için &&, bit manipülasyonu için & kullanın.

Çoğu dilde ~1 neden -2’ye eşittir?

1 üzerindeki bitwise NOT her biti çevirerek birin tümleyenini üretir. İkinin tümleyenli tam sayı temsilinde, x değerinin tüm bitlerini çevirmek -(x + 1) verir; dolayısıyla ~1 eşittir -2, ~0 eşittir -1 ve ~(-1) eşittir 0. Bu özdeşlik JavaScript, Python, Go, C, Rust ve işaretli tam sayıları ikinin tümleyeninde saklayan diğer tüm dillerde geçerlidir.

x << 1 gerçekten x * 2’den daha hızlı mı?

Pratikte değil. Her modern derleyici x * 2 ifadesini tanır ve makine düzeyinde aynı kaydırma komutunu yayar; dolayısıyla x86 veya ARM’de kıyaslamalar ölçülebilir bir fark göstermez. Okunurluk için x * 2 kullanın; << ifadesini bilinçli olarak bitler üzerinde düşündüğünüz durumlara — bir bit maskesi oluşturmak veya yapılandırılmış kimlikleri paketlemek gibi — saklayın.

JavaScript 64 bit bitwise işlemleri destekler mi?

JavaScript standart &, |, ^, <<, >> operatörleriyle 64 bit bitwise işlemleri desteklemez, çünkü bu operatörler işlem çalışmadan önce operandları 32 bit işaretli tam sayılara zorlar. 64 bit veya daha büyük değerler için 1n << 40n gibi BigInt literal’leri kullanın; bunlar kendi eşleşen operatörleriyle keyfi hassasiyetli bitwise işlemler sunar.

Ayarlı bitlerin sayısını verimli biçimde nasıl sayarım?

Dilinizin yerleşiğini kullanın: Go’da bits.OnesCount, Java’da Integer.bitCount, Python 3.10+‘da .bit_count(), C/C++‘da popcount intrinsic’leri. Bunlar modern x86 ve ARM üzerinde tek bir POPCNT CPU komutuna eşlenir.

Bir boolean struct yerine ne zaman bit maskesi bayrakları kullanmalıyım?

Çok sayıda booleanı kompakt biçimde saklamanız gerektiğinde (veritabanları, ağ protokolleri, dosya biçimleri) veya flags & REQUIRED_MASK gibi tek bir AND ile kombinasyonları hızlıca test etmek istediğinizde bit maskesi bayraklarını kullanın. Alanlar farklı türlerde olduğunda, açıklayıcı debug çıktısına ihtiyaç duyduğunuzda veya birkaç bayt bellekten daha çok okunurluk önemli olduğunda boolean struct’ı tercih edin.

Bit genişliğinden fazla kaydırdığımda ne olur?

C/C++‘da tanımsızdır. JavaScript’te kaydırma sayısı mod 32 alınır, dolayısıyla 1 << 32 sonucu 0 değil 1’dir. Python’da genişlik olmadığı için 1 << 100 yalnızca daha büyük bir tam sayıdır. Aşırı kaydırma davranışına asla güvenmeyin; gerekirse kaydırma sayısını kendiniz maskeleyin.

Python’un ~5 ifadesi neden 2 yerine -6 veriyor?

Python tam sayılarının sabit genişliği yoktur, dolayısıyla ikinin tümleyeni kavramsal olarak sonsuza uzanır. ~5 eşittir -(5 + 1) = -6; ikinin tümleyenini kullanan her dilde aynıdır. 8 bit “tersine çevrilmiş” değer 250’yi istiyorsanız maskeleyin: (~5) & 0xFF.

XOR şifreleme güvenli mi?

Mesaj kadar uzun, gerçekten rastgele bir anahtarla one-time pad bilgi kuramı açısından kırılmazdır. Aynı anahtarı mesajlar arasında yeniden kullanmak felaket düzeyinde güvensizdir ve kısa, tekrarlanan bir anahtarla standart XOR “şifrelemesi” son derece kolay biçimde kırılır. AES ve ChaCha20 gibi gerçek şifreler XOR’u dahili olarak kullanır, ancak birçok adımdan biri olarak.

Elle ikinin tümleyeniyle bir negatif sayıyı nasıl gösteririm?

Pozitif değeri hedef genişlikte ikilik yazın, her biti çevirin, sonra 1 ekleyin. Örnek: 8 bit’te -5 = 00000101 → çevirin 11111010 → 1 ekleyin → 11111011. Sayı Tabanı Dönüştürücü aracımızla 251’i (11111011’in işaretsiz yorumu) dönüştürerek doğrulayın ve 11111011 aldığınızdan emin olun.

İlgili araçlar ve ileri okuma