[Linux-programlama] BitWise Üzerine

---------

[Linux-programlama] BitWise Üzerine

From: Tuncay BAŞ <tuncay_at_bir.net.tr>
Date: Mon, 21 Apr 2008 17:43:54 +0300
Message-ID: <008301c8a3be$1fd36300$39a0aed4@net>

Kaynak : http://www.engindumlu.com/

Genelde ve günlük hayatta sürekli 10'luk sistemi kullandığımız için 0 ve 1
lerden oluşan ikilik sistemde işlem yapmak herkesi ilk anda düşündürür.

Birkaç örnekle hemen ikili sayıları hatırlayalım.

10'luk sayı sistemindeki 20487 sayısını düşünün

20487 = (2 * 104) + (0 * 103) + (4 * 102) + (8 * 101)+ (7 * 100)

Taban 10 olduğu için en büyük rakam 10 - 1 = 9 olabilir

Ancak ikilik sistemde ise taban 2 olduğu için en büyük 1 yazabiliriz

110101 = (1 * 25) + (1 * 24) + (0 * 23) + (1 * 22) + (0 * 21) + (1 * 20) =
32 + 16 + 0 + 4 + 0 + 1 = 53

      1
     1
     0
     1
     0
     1

      25
     24
     23
     22
     21
     20

İkili sayının (binary digit - bit) bilgisayarlar için özel bir anlamı vardır

Veriler, formatı veya uzunluğu her ne olursa olsun 0 ve 1'ler katarı olarak
depolanır ( devre açık veya kapalı - akım var veya yok.)

8 ikile bayt (byte) denir. Örneğin; 11010001 , 01000101

( 1 byte = 8 bit)

      1
     1
     1
     1
     1
     1
     1
     1
     =
     11111111(2)

      27
     26
     25
     24
     23
     22
     21
     20

      128
     64
     32
     16
     8
     4
     2
     1
     =
     255(10)

Peki bitwise işlemler nedir?

Operatör & (And)

İki sayıda ortak olan bit'leri almanızı sağlar ( $a ve $b 'deki ortak olan
bit'ler )

11010101 & 01101001

      1
     1
     0
     1
     0
     1
     0
     1
     =
     11010101(2)

      0
     1
     1
     0
     1
     0
     0
     1
     =
     01101001(2)

      0
     1
     0
     0
     0
     0
     0
     1
     &
     01000001(2)

Tablodanda kolayca anlaşılacağı gibi bu işlem bize iki sayıdaki ortak olan
bit'leri veriyor.

Operatör | (Or)

İşleme giren sayılardan birinde veya diğerinde olan bit'leri almamızı sağlar
( $a veya $b 'deki bitler )

11010101 | 01101001

      1
     1
     0
     1
     0
     1
     0
     1
     =
     11010101(2)

      0
     1
     1
     0
     1
     0
     0
     1
     =
     01101001(2)

      1
     1
     1
     1
     1
     1
     0
     1
     &
     11111101(2)

Ele alınan basamakta sayıların herhangi birinde 1 olması sonucu 1 aksi halde
0 yapıyor.

Operatör ^ (Xor)

İşleme giren sayılardan yalnız birinde olan bit'leri almamızı sağlar ($a
veya $b de olan ama her ikisinde olmayan bit'ler )

11010101 ^ 01101001

      1
     1
     0
     1
     0
     1
     0
     1
     =
     11010101(2)

      0
     1
     1
     0
     1
     0
     0
     1
     =
     01101001(2)

      1
     0
     1
     1
     1
     1
     0
     0
     &
     10111100(2)

Operatör ~ (Not)

Sayıdaki olmayan bit'leri yani 0'ları 1, 1'leride 0 yapar.

~ 11010101

      1
     1
     0
     1
     0
     1
     0
     1
     =
     11010101(2)

      0
     0
     1
     0
     1
     0
     1
     0
     =
     00101010(2)

Operatör << (Shift Left)

İşleme sol taraftan giren sayıyı ikili bazda sağ taraftaki sayı kadar sola
kaydırır.

00010101 << 3

      0
     0
     0
     1
     0
     1
     0
     1
     =
     00010101(2)

      1
     0
     1
     0
     1
     0
     0
     0
     =
     10101000(2)

Bu kısaca (00010101) 2 sayısını 23 ile çarpmak demektir.

Operatör >> (Shift Right)

İşleme sol taraftan giren sayıyı ikili bazda sağ taraftaki sayı kadar sağa
kaydırır.

10101000 >> 3

      1
     0
     1
     0
     1
     0
     0
     0
     =
     10101000(2)

      0
     0
     0
     1
     0
     1
     0
     1
     =
     00010101(2)

Bu kısaca (10101000)2 sayısını 23 'e bölmek demektir.

Son olarak php'den örnek vermek gerekirse;

Bilgi mesajları haricinde tüm hataları görmek için error_reporting(E_ALL &
~E_NOTICE); kullanıyoruz. (veya türevleri)

PLAIN TEXT
PHP:
  1.. echo E_ALL."\n"; // 6143
  2..
  3.. echo E_NOTICE."\n"; // 8
  4..
  5.. echo decbin(E_ALL)."\n"; // 1011111111111
  6..
  7.. echo decbin(E_NOTICE)."\n"; // 1000
  8..
  9.. echo (E_ALL & ~E_NOTICE)."\n"; // 6135
  10..
  11.. echo decbin(E_ALL & ~E_NOTICE); // 1011111110111
  12..
  13.. ?>
Bu işlemi biraz daha detaylı inceleyelim.

E_NOTICE sabitinde olmayan(~) bit'lerle E_ALL sabitindeki bitlerle ortak
olanlarını(&) alıp, error_reporting fonksiyonuna gönderiyoruz.

      E_ALL 1 0 1 1 1 1 1 1 1 1 1 1 1
      E_NOTICE 0 0 0 0 0 0 0 0 0 1 0 0 0

Hiçbir bitwise işlemi olmadan önce sayılarımızın durumu yukardaki gibi.
~E_NOTICE 'in değerine bakalım..

      E_NOTICE 0 0 0 0 0 0 0 0 0 1 0 0 0
      ~E_NOTICE 1 1 1 1 1 1 1 1 1 0 1 1 1

Not: php integer'ları 32 bit olarak saklar. Yani ~E_NOTICE
11111111111111111111111111110111 olur. E_ALL ise aslında
0000000000000000000001011111111111 'dır.

Tablo uzayacağı için ve yaptığımız & işlemi ilk baştaki 21 bit
karşılaştırmasından 0 döndüreceği için burada göstermiyorum.

Sonuç olarak E_ALL ile değerini öğrendiğimiz ~E_NOTICE arasında & işlemini
yaparsak;

      E_ALL 1 0 1 1 1 1 1 1 1 1 1 1 1 = 6143
      ~E_NOTICE 1 1 1 1 1 1 1 1 1 0 1 1 1
      Sonuç 1 0 1 1 1 1 1 1 1 0 1 1 1 = 6135

error_reporting(6135);

_______________________________________________
Linux-programlama mailing list
Linux-programlama_at_liste.linux.org.tr
http://liste.linux.org.tr/mailman/listinfo/linux-programlama
Received on Mon 21 Apr 2008 - 16:57:31 EEST

---------

Bu arsiv hypermail 2.2.0 tarafindan uretilmistir.