Bit Maske mi, Karşılaştırma mı? 8'lik Biti İki Yoldan Okuyan İki Program
Bir hata kelimesinin 8'lik bitini 'kelime & 8' ile okudum, 'kelime = 8' ile okuyan meslektaşım ise yalnızca tek hatanın geldiği anda görüyordu. Bit maskenin neden 'kelimenin geri kalanı ne olursa olsun' çalıştığını ve & 8'in 0'dan farklı olması ile = 8'in farkını kendi vaka üzerinden anlatıyorum.

Perşembe, öğleden sonra. Bir hata kelimesi (error word) üzerinde çalışıyorduk. 16 bitlik bir kelime, her bit bir hata: bit 0 “kapak açık,” bit 1 “gerilim düşük,” bit 3 “8’lik bit — motor faz hatası,” bit 5 “soğutma.” Operatör “abi faz hatası alarmı gelince diğerleri de gelince makine duruyor, ama sadece faz hatası gelince durmuyor” dedi. “Sadece faz hatası” derken kastettiği, kelimenin başka bir bitinin ON olmadığı anlardı.
Benim satırım şuydu:
if (hata_kelime and 8 <> 0) alarm_faz := true;
Meslektaşımın satırı, üç ay önceki bir versiyonda, şuydu:
if (hata_kelime = 8) alarm_faz := true;
İkisi de “8’lik biti kontrol ediyor” gibi duruyordu. Ama ikisi de aynı şeyi yapmıyordu.
= 8, “Sadece ve Sadece 8” Demektir
hata_kelime = 8 ne zaman doğru? Kelimenin tamamının 8 olduğu an. Yani bit 3’ün ON olduğu ve bit 0, 1, 5… hepsinin OFF olduğu tek an. Faz hatası tek başına geldiğinde, kelime 8’di, alarm tetikleniyordu. Ama faz hatası ile kapak açığı aynı anda geldiğinde — bit 3 ve bit 0 — kelime 8 değil, 12 oluyordu. 12 = 8 → yanlış. Alarm, tam da iki hatanın üst üste geldiği anda sönüyordu.
Sahada bu, en tehlikeli türdür: sorun, tek hatada değil, iki hatanın birleşmesinde kayboluyor. Operatör “nasıl olur, faz hatası var ama alarm yok” diyor. Sen de bakıyorsun, kelime 12, evet bit 3 ON. Ama senin satırın 12’yi görmüyor, 8’i görüyor.
& 8, “8’lik Bit Ne Olursa Olsun” Demektir
hata_kelime and 8 ne yapar? Kelimenin tüm bitlerini 8’lik maske ile AND’ler. 8’in binary’si 00001000. AND, iki bitin de 1 olduğu yerde 1 verir. Yani sonuç, yalnızca bit 3’ün durumudur; kelimenin geri kalanı ne olursa olsun, and 8 ya 8 ya 0 döner. Sonra <> 0, “8’lik bit ON mu?” diye sorar.
if (hata_kelime and 8 <> 0) alarm_faz := true;
Kelime 8 mi, 12 mi, 24 mü — fark etmez. Bit 3 ON ise, and 8 = 8, <> 0 doğru, alarm. Bit 3 OFF ise, and 8 = 0, alarm yok. Diğer bitler, bu satırın umurunda bile değil.
Masadaki maliyeti: bir satır. Simülatörde kelimeye 12 ver, = 8 satırının sönüp & 8 satırının yandığını üç saniyede görürsün. Sahadaki maliyeti: üç ay. Çünkü “iki hatanın üst üste geldiği” an, ayda bir geliyordu.
Kural: Biti Oku, Kelimeyi Tahmin Etme
Artık kuralım şu: bir hata kelimesinin tek bir bitine bakacaksan, maske + AND + sıfır karşılaştırması kullan. kelime and (1 << n) ya da pratikte kelime and 8, kelime and 1, kelime and 2. Asla kelime = 8 yazma; o, “yalnızca bu hata ve başka hiçbir şey” demektir, ve “başka hiçbir şey” sahada nadir bir lükstür.
Bir de ek: maskeyi sabit sayı olarak değil, isimli bir sabit olarak ver. BIT_FAZ := 8, BIT_KAPAK := 1. hata_kelime and BIT_FAZ <> 0 okunur. Üç ay sonra “8 neydi” diye sayıya bakıp saymak zorunda kalmazsın. Sayı, unutulur; isim, durur.
O perşembe, o “sadece faz hatası” cümlesi, bir and ile düzeldi. Operatör “abi iki hata birden gelse de şimdi duruyor” dedi. Ben de o an anladım ki, = 8 yazan ben, “temiz” bir an arıyordum. Saha temiz an vermez; saha, bitleri üst üste verir. Maske, üst üste verilenlerin içinden tek bir bitini ayıklar.
İpucu serisinin bir sonraki halkasında, “bir sayacım 32767’de takıldı, ertesi gün açtığımda eksi bir sayı gösteriyordu” diye başlayan hikâyeyi anlatıyorum. 16 bitlik bir INT’in neden 32768’de -32768’e sarıp geri döndüğü.