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.
Eğer &, | ve ^ için her iki terim de dize ise terimlerdeki karakterlerin ASCII değerleri üzerinde işlem yapılır ve sonuç bir dize olur. Tüm diğer durumlarda, her iki terim tamsayıya dönüştürülür ve sonuç tamsayı olur.
~ işleci için terim bir dize ise, terimdeki karakterlerin ASCII değerleri üzerinde işlem yapılır ve sonuç bir dize olur. Aksi takdirde, terim ve sonuç tamsayı olarak ele alınır.
<< ve >> işleçleri için her iki terim ve sonuç daima tamsayı olarak ele alını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ı
PHP 7.0 öncesinde, tamsayıları, sistem uzun tamsayı genişliğinden büyük veya ona eşit olan değerlere göre veya negatif sayılara göre kaydırmak, tanımlanmamış davranışlarla sonuçlanır. Başka bir deyişle, PHP 5.x kullanıyorsanız, 32 bitlik sistemlerde 31 bitten, 64 bitlik sistemlerde 63 bitten fazla kaydırma yapmayın.
Use functions from the gmp extension for bitwise manipulation on numbers beyond PHP_INT_MAX'ın ötesindeki sayılar üzerinde bitsel işlemler için gmp eklentisindeki işlevleri kullanın.
Ayrıca bakınız: pack(), unpack(), gmp_and(), gmp_or(), gmp_xor(), gmp_testbit(), gmp_clrbit()