Bit temelli (bitwise) operatörler ile mantıksal operatörler arasındaki fark

Bit temelli (bitwise) operatörler ile mantıksal operatörler arasındaki fark

6 Temmuz 2017 0 Yazar: Cem Kefeli

Sadece tek bir karakterin yazılımınızın performansını ve gidişatını nasıl kolayca değişitirebileceğini görmek istiyorsanız yazının devamını okumanızı öneririm.

İlk önce bit temelli (bitwise) ‘ve’ (&) işaretinden bahsetmek istiyorum. Bit temelli işlemler, meşhur ‘Olmak ya da olmamak, işte bütüm mesele bu!’ sözüne uygun bir şekilde var olan (1) ya da olmayan (0) değerlerin birbiri ile münasebeti ile ilgileniyor. ‘veya’ (|) operatörünü bir matematiksel işaret olarak ele alacak olursak toplama işlemine denk tutabiliriz. Eğer ‘veya’ işlemine girecek değerlerden herhangi birisi anlamlıysa yani ‘1’ ise sonuç da anlamlı (true) olacaktır. Yapılan işlem içerisinde yalnızca tek bir 1’in olması sonucun ‘1’ olması için yeterlidir. ‘ve’ (&) operatörünü bir matematiksel işaret olarak ele alacak olursak da çarpma işlemine denk tutabiliriz. Eğer ‘ve’ işlemine girecek değerlerden herhangi birisi anlamsızsa yani ‘0’ ise sonuç da anlamsız (false) olacaktır. Yani yapılan işlem içerisinde yalnızca tek bir ‘0’ın olması sonucun ‘0’ olması için yeterlidir. Bu basit bit temelli işler için bir değer/sonuç tablosu oluşturmak gerekirse sağdaki tablo karşımıza çıkar.

and/or operators
and/or operators

Bu ön bilgilerden sonra şimdi artık yazının ana konusuna gelecek olursak asıl önemli noktalardan birisi de mantıksal işlemler için ‘ve’ ve ‘veya’ operatörlerinin nasıl yorumlanacağıdır. Öncelikle şunu belirtmek gerekir ki eğer bit temelli işlem yapacak olursanız sonuç da yine bit temelli olacaktır. Çalışma anında bit temelli işlemlerde yorum gücü katma değeri yoktur. Sırası ile istenilen hesaplamadaki bit temelli işlemler yapılır, nihayetinde de yine bit temelli bir sonuç elde edilir. Mantıksal işlemlerde ise uygulama çalışma anında yine bit değerler üzerinden bir işlem yapılmaktadır ama bu sefer bir yorumlama katma değeri de söz konusudur. Biraz açacak olursak örneğin bir ‘if’ koşulu içerisinde yer alan aşağıdaki ifadeyi inceleyelim;

Örnek-1: Bit temelli koşul sınaması (&)

/**
 *
 * @author cem.kefeli
 */
public class JavaApplication1 {

    public static void main(String[] args) {
        if (method1() & method2() & method3() & method4()) {
            System.out.println("If koşulu sağlandı.");
        } else {
            System.out.println("If koşulu sağlanmadı.");
        }
    }

    public static boolean method1() {
        System.out.println("Method-1");

        return true;
    }

    public static boolean method2() {
        System.out.println("Method-2");

        return false;
    }

    public static boolean method3() {
        System.out.println("Method-3");

        return true;
    }

    public static boolean method4() {
        System.out.println("Method-4");

        return true;
    }
}

Program Çıktısı:

debug:
Method-1
Method-2
Method-3
Method-4
If koşulu sağlanmadı.

Uygulama çıktısından da anlaşıldığı gibi ‘if’ koşulu içerisindeki tüm koşul sınamaları tek tek çalıştırıldı ve nihayetinde bu koşul sınamalarının tümü için topluca bir sonuç elde edilerek uygulama akışı oluşturuldu. Bu aşamada dikkatinizi çeken bir nokta olmalı. O da şu; ‘if içerindeki koşul sınamalarımızın tümü ‘ve’ operatörü ile birbirine bağlanmış durumda. yani koşul sınamalarından birisinin bile anlamsız olması if koşulunun sağlanmaması için yeterli. O halde ikinci koşul sınamasından sonra neden diğer koşul sınamalarına gereksiz yere efor harcayayım ve devam edeyim ki?’ İşte zaten bu yazı için kritik ve anlamlı soru da tam olarak da bu soru. Bu sorunun cevabı olarak da ‘Evet. İkinci koşul sınaması sonrasında zaten durum belli oldu, diğer koşul sınamalarını kontrol etmeye gerek yok.’ cevabını verebilmemiz için ise bit temelli değil de mantıksal operatörleri (&& ||) kullanmamız gerekir. Aşağıdaki kod parçacıkları hem mantıksal ‘ve’ hem de mantıksal ‘veya’ için avantajları açık bir şekilde gözler önüne seriyor;

/**
 *
 * @author cem.kefeli
 */
public class JavaApplication1 {

    public static void main(String[] args) {
        if (method1() && method2() && method3() && method4()) {
            System.out.println("If koşulu sağlandı.");
        } else {
            System.out.println("If koşulu sağlanmadı.");
        }
    }

    .
    .
    .
}

Program Çıktısı:

debug:
Method-1
Method-2
If koşulu sağlanmadı.
/**
 *
 * @author cem.kefeli
 */
public class JavaApplication1 {

    public static void main(String[] args) {
        if (method1() | method2() | method3() | method4()) {
            System.out.println("If koşulu sağlandı.");
        } else {
            System.out.println("If koşulu sağlanmadı.");
        }
    }

    .
    .
    .
}

Program Çıktısı:

debug:
Method-1
Method-2
Method-3
Method-4
If koşulu sağlandı.
/**
 *
 * @author cem.kefeli
 */
public class JavaApplication1 {

    public static void main(String[] args) {
        if (method2() | method1() | method3() | method4()) {
            System.out.println("If koşulu sağlandı.");
        } else {
            System.out.println("If koşulu sağlanmadı.");
        }
    }

    .
    .
    .
}

Program Çıktısı:

debug:
Method-1
Method-2
If koşulu sağlandı.

Örneği inceleyecek olursanız tam da istediğimiz gibi ikinci koşul sınamasından sonra diğer koşul sınamalarının kontrol edilmesi bir anlam ifade etmediği için hiç yapılmamıştır ve gereksiz kaynak ve zaman kullanımının böylece önüne geçilmiştir.