Bitsel işleçler, bir tamsayının içindeki belli bitleri 0 ya da 1 yaparlar.
Örnek | İsim | Sonuç |
---|---|---|
$a & $b |
Ve | Hem $a hem de $b'de 1 olan bitler sonuçta 1 yapılır. |
$a | $b |
Veya | $a veya $b'de 1 olan bitler sonuçta 1 yapılır. |
$a ^ $b |
Ayrıcalıklı Veya | Hem $a hem de $b'de 0 veya 1 olan bitler sonuçta 0, diğerleri 1 yapılır. |
~ $a |
Değil | $a'nın 0 olan bitleri 1, 1 olanları 0 yapılır. |
$a << $b |
Sola kaydırma | $a'nın bitleri $b adım sola kaydırılır (her adım ikiyle çarpma işlemine denktir). |
$a >> $b |
Sağa kaydırma | $a'nın bitleri $b adım sağa kaydırılır (her adım ikiye bölme işlemine denktir). |
PHP'de bit kaydırma bir aritmetik işlemdir. Kaydırma sonucu her iki uçtan da taşan bitler silinir. Sola kaydırmada sağdan eksilen bitler sıfırlarla doldurulur, bu arada işaret biti soldan taşarak silinir, yani sola kaydırmada terimin işareti korunmaz. Sağa kaldırmada ise işaret biti yerinden oynatılmaz, yani sağa kaydırmada terimin işareti korunur.
Bir işlemin öncelik almasını istiyorsanız yaylı ayraçları kullanın. Örneğin, $a & $b == true işleminde önce eşitlik sonra bitsel VE uygulanırken ($a & $b) == true işleminde ise önce bitsel VE sonra eşitlik uygulanır.
Veri türü dönüşümlerinde dikkatli olun. Eğer sol ve sağ taraf değiştirgelerinin ikisi de dizge ise bitsel işleçler terimlerdeki karakterlerin ASCII değerleri üzerinde işlem yapacaktır.
PHP'nin error_reporting yönergesi gerçekte neler olup bittiğini göstermek
için bitsel değerler kullanır. Sadece bilgilendirmeleri değil hataların
tümünü görmek isterseniz php.ini dosyasında ilgili yere şunu yazın:
E_ALL & ~E_NOTICE
Bu E_ALL için şöyle çalışır:00000000000000000111011111111111
Keza E_NOTICE...00000000000000000000000000001000
... ve ~ ile ters çevrilerek:11111111111111111111111111110111
Son olarak, her iki değer üzerinde etkin bitleri bulmak için VE (&) işlecini kullanır:00000000000000000111011111110111
Bunu sağlamanın bir başka yolu da sadece bir değerde veya diğerinde etkin
bitleri bulmak için XOR (^) kullanmaktır:
E_ALL ^ E_NOTICE
error_reporting yönergesi bitleri etkin kılmayı göstermek için de
kullanılabilir. Sadece hataları ve kurtarılabilir göstermenin yolu:
E_ERROR | E_RECOVERABLE_ERROR
Bu işlem etkin bitleri almak için00000000000000000000000000000001
ve00000000000000000001000000000000
E_ERROR'ları üzerinde VEYA (|) işlecini kullanır:00000000000000000001000000000001
Örnek 1 - Tamsayılar üzerinde bitsel işlemler
<?php
/*
* Üstteki bölümü yoksayın,
* çıktıyı iyileştirmek için biçemlemekten başka birşey yapmıyor.
*/
$format = '(%1$2d = %1$04b) = (%2$2d = %2$04b)'
. ' %3$s (%4$2d = %4$04b)' . "\n";
echo <<<EOH
--------- --------- -- ---------
sonuç değer işl dnm
--------- --------- -- ---------
EOH;
/*
* Örnekler burada.
*/
$değerler = array(0, 1, 2, 4, 8);
$dnm = 1 + 4;
echo "\n Bitsel VE \n";
foreach ($değerler as $değer) {
$sonuç = $değer & $dnm;
printf($format, $sonuç, $değer, '&', $dnm);
}
echo "\n Bitsel Ayrıcalıklı VEYA \n";
foreach ($değerler as $değer) {
$sonuç = $değer | $dnm;
printf($format, $sonuç, $değer, '|', $dnm);
}
echo "\n Bitsel Ayrıcalıklı VEYA (XOR) \n";
foreach ($değerler as $değer) {
$sonuç = $değer ^ $dnm;
printf($format, $sonuç, $değer, '^', $dnm);
}
?>
Yukarıdaki örneğin çıktısı:
--------- --------- -- --------- sonuç değer işl dnm --------- --------- -- --------- Bitsel VE ( 0 = 0000) = ( 0 = 0000) & ( 5 = 0101) ( 1 = 0001) = ( 1 = 0001) & ( 5 = 0101) ( 0 = 0000) = ( 2 = 0010) & ( 5 = 0101) ( 4 = 0100) = ( 4 = 0100) & ( 5 = 0101) ( 0 = 0000) = ( 8 = 1000) & ( 5 = 0101) Bitsel Ayrıcalıklı VEYA ( 5 = 0101) = ( 0 = 0000) | ( 5 = 0101) ( 5 = 0101) = ( 1 = 0001) | ( 5 = 0101) ( 7 = 0111) = ( 2 = 0010) | ( 5 = 0101) ( 5 = 0101) = ( 4 = 0100) | ( 5 = 0101) (13 = 1101) = ( 8 = 1000) | ( 5 = 0101) Bitsel Ayrıcalıklı VEYA (XOR) ( 5 = 0101) = ( 0 = 0000) ^ ( 5 = 0101) ( 4 = 0100) = ( 1 = 0001) ^ ( 5 = 0101) ( 7 = 0111) = ( 2 = 0010) ^ ( 5 = 0101) ( 1 = 0001) = ( 4 = 0100) ^ ( 5 = 0101) (13 = 1101) = ( 8 = 1000) ^ ( 5 = 0101)
Örnek 2 - Dizgeler üzerinde bitsel işlemler
<?php
echo 12 ^ 9; // '5' çıktılar
echo "12" ^ "9"; // Gerisilme karakterini çıktılar (ASCII 8)
// ('1' (ascii 49)) ^ ('9' (ascii 57)) = ASCII 8
echo "hallo" ^ "hello"; // Çıktılanan ASCII değerler #0 #4 #0 #0 #0
// 'a' ^ 'e' = #4
echo 2 ^ "3"; // 1 çıktılar
// 2 ^ ((int)"3") == 1
echo "2" ^ 3; // 1 çıktılar
// ((int)"2") ^ 3 == 1
?>
Örnek 3 - Tamsayılarda bit kaydırma
<?php
/*
* Bunlar örnektir.
*/
echo "\n--- POZİTİF TAMSAYILARDA SAĞA BİT KAYDIRMA ---\n";
$dgr = 4;
$hane = 1;
$snç = $dgr >> $hane;
p($snç, $dgr, '>>', $hane, 'işaret bitinin kopyası sola kaydırıldı');
$dgr = 4;
$hane = 2;
$snç = $dgr >> $hane;
p($snç, $dgr, '>>', $hane);
$dgr = 4;
$hane = 3;
$snç = $dgr >> $hane;
p($snç, $dgr, '>>', $hane, 'bitler sağa kaydırıldı');
$dgr = 4;
$hane = 4;
$snç = $dgr >> $hane;
p($snç, $dgr, '>>', $hane, 'yukarıdakiyle aynı; 0\'dan sonrası kaydırılamaz');
echo "\n--- NEGATİF TAMSAYILARDA SAĞA BİT KAYDIRMA ---\n";
$dgr = -4;
$hane = 1;
$snç = $dgr >> $hane;
p($snç, $dgr, '>>', $hane, 'işaret bitinin kopyası sola kaydırıldı');
$dgr = -4;
$hane = 2;
$snç = $dgr >> $hane;
p($snç, $dgr, '>>', $hane, 'bitler sağa kaydırıldı');
$dgr = -4;
$hane = 3;
$snç = $dgr >> $hane;
p($snç, $dgr, '>>', $hane, 'yukarıdakiyle aynı; -1\'dan sonrası kaydırılamaz');
echo "\n--- POZİTİF TAMSAYILARDA SOLA BİT KAYDIRMA ---\n";
$dgr = 4;
$hane = 1;
$snç = $dgr << $hane;
p($snç, $dgr, '<<', $hane, 'sağ taraf sıfırlarla doldurulur');
$dgr = 4;
$hane = (PHP_INT_SIZE * 8) - 4;
$snç = $dgr << $hane;
p($snç, $dgr, '<<', $hane);
$dgr = 4;
$hane = (PHP_INT_SIZE * 8) - 3;
$snç = $dgr << $hane;
p($snç, $dgr, '<<', $hane, 'işaret bitleri dışa kaydırılır');
$dgr = 4;
$hane = (PHP_INT_SIZE * 8) - 2;
$snç = $dgr << $hane;
p($snç, $dgr, '<<', $hane, 'bitler sola kaydırıldı');
echo "\n--- NEGATİF TAMSAYILARDA SOLA BİT KAYDIRMA ---\n";
$dgr = -4;
$hane = 1;
$snç = $dgr << $hane;
p($snç, $dgr, '<<', $hane, 'sağ taraf sıfırlarla doldurulur');
$dgr = -4;
$hane = (PHP_INT_SIZE * 8) - 3;
$snç = $dgr << $hane;
p($snç, $dgr, '<<', $hane);
$dgr = -4;
$hane = (PHP_INT_SIZE * 8) - 2;
$snç = $dgr << $hane;
p($snç, $dgr, '<<', $hane, 'işaret biti dahil, bitler soldan dışa kaydırıldı');
/*
* Bundan sonrasını yoksayın; çıktıyı biçemlemekten başka bir şey yapmıyor.
*/
function p($snç, $dgr, $op, $hane, $ilt = '') {
$format = '%0' . (PHP_INT_SIZE * 8) . "b\n";
printf("İfade: %d = %d %s %d\n", $snç, $dgr, $op, $hane);
echo " Onluk:\n";
printf(" değer=%d\n", $dgr);
printf(" sonuç=%d\n", $snç);
echo " İkilik:\n";
printf(' değer=' . $format, $dgr);
printf(' sonuç=' . $format, $snç);
if ($ilt) {
echo " DİKKAT: $ilt\n";
}
echo "\n";
}
?>
Yukarıdaki örneğin 32 bitlik makinelerdeki çıktısı:
--- POZİTİF TAMSAYILARDA SAĞA BİT KAYDIRMA --- İfade: 2 = 4 >> 1 Onluk: değer=4 sonuç=2 İkilik: değer=000000000000000000000000000100 sonuç=000000000000000000000000000010 DİKKAT: işaret bitinin kopyası sola kaydırıldı İfade: 1 = 4 >> 2 Onluk: değer=4 sonuç=1 İkilik: değer=000000000000000000000000000100 sonuç=000000000000000000000000000001 İfade: 0 = 4 >> 3 Onluk: değer=4 sonuç=0 İkilik: değer=000000000000000000000000000100 sonuç=000000000000000000000000000000 DİKKAT: bitler sağa kaydırıldı İfade: 0 = 4 >> 4 Onluk: değer=4 sonuç=0 İkilik: değer=000000000000000000000000000100 sonuç=000000000000000000000000000000 DİKKAT: yukarıdakiyle aynı; 0'dan sonrası kaydırılamaz --- NEGATİF TAMSAYILARDA SAĞA BİT KAYDIRMA --- İfade: -2 = -4 >> 1 Onluk: değer=-4 sonuç=-2 İkilik: değer=111111111111111111111111111100 sonuç=111111111111111111111111111110 DİKKAT: işaret bitinin kopyası sola kaydırıldı İfade: -1 = -4 >> 2 Onluk: değer=-4 sonuç=-1 İkilik: değer=111111111111111111111111111100 sonuç=111111111111111111111111111111 DİKKAT: bitler sağa kaydırıldı İfade: -1 = -4 >> 3 Onluk: değer=-4 sonuç=-1 İkilik: değer=111111111111111111111111111100 sonuç=111111111111111111111111111111 DİKKAT: yukarıdakiyle aynı; -1'dan sonrası kaydırılamaz --- POZİTİF TAMSAYILARDA SOLA BİT KAYDIRMA --- İfade: 8 = 4 << 1 Onluk: değer=4 sonuç=8 İkilik: değer=000000000000000000000000000100 sonuç=000000000000000000000000001000 DİKKAT: sağ taraf sıfırlarla doldurulur İfade: 4611686018427387904 = 4 << 60 Onluk: değer=4 sonuç=4611686018427387904 İkilik: değer=000000000000000000000000000100 sonuç=010000000000000000000000000000 İfade: -9223372036854775808 = 4 << 61 Onluk: değer=4 sonuç=-9223372036854775808 İkilik: değer=000000000000000000000000000100 sonuç=100000000000000000000000000000 DİKKAT: işaret bitleri dışa kaydırılır İfade: 0 = 4 << 62 Onluk: değer=4 sonuç=0 İkilik: değer=000000000000000000000000000100 sonuç=000000000000000000000000000000 DİKKAT: bitler sola kaydırıldı --- NEGATİF TAMSAYILARDA SOLA BİT KAYDIRMA --- İfade: -8 = -4 << 1 Onluk: değer=-4 sonuç=-8 İkilik: değer=111111111111111111111111111100 sonuç=111111111111111111111111111000 DİKKAT: sağ taraf sıfırlarla doldurulur İfade: -9223372036854775808 = -4 << 61 Onluk: değer=-4 sonuç=-9223372036854775808 İkilik: değer=111111111111111111111111111100 sonuç=100000000000000000000000000000 İfade: 0 = -4 << 62 Onluk: değer=-4 sonuç=0 İkilik: değer=111111111111111111111111111100 sonuç=000000000000000000000000000000 DİKKAT: işaret biti dahil, bitler soldan dışa kaydırıldı
Yukarıdaki örneğin 64 bitlik makinelerdeki çıktısı:
--- POZİTİF TAMSAYILARDA SAĞA BİT KAYDIRMA --- İfade: 2 = 4 >> 1 Onluk: değer=4 sonuç=2 İkilik: değer=0000000000000000000000000000000000000000000000000000000000000100 sonuç=0000000000000000000000000000000000000000000000000000000000000010 DİKKAT: işaret bitinin kopyası sola kaydırıldı İfade: 1 = 4 >> 2 Onluk: değer=4 sonuç=1 İkilik: değer=0000000000000000000000000000000000000000000000000000000000000100 sonuç=0000000000000000000000000000000000000000000000000000000000000001 İfade: 0 = 4 >> 3 Onluk: değer=4 sonuç=0 İkilik: değer=0000000000000000000000000000000000000000000000000000000000000100 sonuç=0000000000000000000000000000000000000000000000000000000000000000 DİKKAT: bitler sağa kaydırıldı İfade: 0 = 4 >> 4 Onluk: değer=4 sonuç=0 İkilik: değer=0000000000000000000000000000000000000000000000000000000000000100 sonuç=0000000000000000000000000000000000000000000000000000000000000000 DİKKAT: yukarıdakiyle aynı; 0'dan sonrası kaydırılamaz --- NEGATİF TAMSAYILARDA SAĞA BİT KAYDIRMA --- İfade: -2 = -4 >> 1 Onluk: değer=-4 sonuç=-2 İkilik: değer=1111111111111111111111111111111111111111111111111111111111111100 sonuç=1111111111111111111111111111111111111111111111111111111111111110 DİKKAT: işaret bitinin kopyası sola kaydırıldı İfade: -1 = -4 >> 2 Onluk: değer=-4 sonuç=-1 İkilik: değer=1111111111111111111111111111111111111111111111111111111111111100 sonuç=1111111111111111111111111111111111111111111111111111111111111111 DİKKAT: bitler sağa kaydırıldı İfade: -1 = -4 >> 3 Onluk: değer=-4 sonuç=-1 İkilik: değer=1111111111111111111111111111111111111111111111111111111111111100 sonuç=1111111111111111111111111111111111111111111111111111111111111111 DİKKAT: yukarıdakiyle aynı; -1'dan sonrası kaydırılamaz --- POZİTİF TAMSAYILARDA SOLA BİT KAYDIRMA --- İfade: 8 = 4 << 1 Onluk: değer=4 sonuç=8 İkilik: değer=0000000000000000000000000000000000000000000000000000000000000100 sonuç=0000000000000000000000000000000000000000000000000000000000001000 DİKKAT: sağ taraf sıfırlarla doldurulur İfade: 4611686018427387904 = 4 << 60 Onluk: değer=4 sonuç=4611686018427387904 İkilik: değer=0000000000000000000000000000000000000000000000000000000000000100 sonuç=0100000000000000000000000000000000000000000000000000000000000000 İfade: -9223372036854775808 = 4 << 61 Onluk: değer=4 sonuç=-9223372036854775808 İkilik: değer=0000000000000000000000000000000000000000000000000000000000000100 sonuç=1000000000000000000000000000000000000000000000000000000000000000 DİKKAT: işaret bitleri dışa kaydırılır İfade: 0 = 4 << 62 Onluk: değer=4 sonuç=0 İkilik: değer=0000000000000000000000000000000000000000000000000000000000000100 sonuç=0000000000000000000000000000000000000000000000000000000000000000 DİKKAT: bitler sola kaydırıldı --- NEGATİF TAMSAYILARDA SOLA BİT KAYDIRMA --- İfade: -8 = -4 << 1 Onluk: değer=-4 sonuç=-8 İkilik: değer=1111111111111111111111111111111111111111111111111111111111111100 sonuç=1111111111111111111111111111111111111111111111111111111111111000 DİKKAT: sağ taraf sıfırlarla doldurulur İfade: -9223372036854775808 = -4 << 61 Onluk: değer=-4 sonuç=-9223372036854775808 İkilik: değer=1111111111111111111111111111111111111111111111111111111111111100 sonuç=1000000000000000000000000000000000000000000000000000000000000000 İfade: 0 = -4 << 62 Onluk: değer=-4 sonuç=0 İkilik: değer=1111111111111111111111111111111111111111111111111111111111111100 sonuç=0000000000000000000000000000000000000000000000000000000000000000 DİKKAT: işaret biti dahil, bitler soldan dışa kaydırıldı
32 bitlik sistemlerde 32 bitten fazla sağa kaydırma yapmayın. 32 bitten daha geniş bir sayıyla sonuçlanacak şekilde sola kaydırma yapmayın. PHP_INT_MAX'tan büyük sayılar üzerinde bitsel işlemler yapacaksanız gmp eklentisindeki işlevleri kullanın.
Ayrıca bakınız: pack(), unpack(), gmp_and(), gmp_or(), gmp_xor(), gmp_testbit(), gmp_clrbit()