Op�rateurs sur les bits
Les op�rateurs sur les bits vous permettent de manipuler les bits dans un entier.
Exemple | Nom | R�sultat |
---|---|---|
$a & $b
|
And (Et) | Les bits positionn�s � 1 dans $a ET dans $b sont positionn�s � 1. |
$a | $b
|
Or (Ou) | Les bits positionn�s � 1 dans $a OU $b sont positionn�s � 1. |
$a ^ $b
|
Xor (ou exclusif) | Les bits positionn�s � 1 dans $a OU dans $b mais pas dans les deux sont positionn�s � 1. |
~ $a
|
Not (Non) | Les bits qui sont positionn�s � 1 dans $a sont positionn�s � 0, et vice versa. |
$a << $b
|
D�calage � gauche | D�cale les bits de $a, $b fois sur la gauche (chaque d�calage �quivaut � une multiplication par 2). |
$a >> $b
|
D�calage � droite | D�calage des bits de $a, $b fois par la droite (chaque d�calage �quivaut � une division par 2). |
Le d�calage de bits en PHP est arithm�tique. Les bits qui sont d�cal�s hors de l'entier sont perdus. Les d�calages � gauche font appara�tre des z�ros � droite, tandis que le bit de signe est d�cal� � gauche, ce qui signifie que le signe de l'entier n'est pas pr�serv�. Les d�calages � droite d�calent aussi le bit de signe sur la droite, ce qui signifie que le signe est pr�serv�.
Utilisez des parenth�ses pour vous assurer que la pr�c�dence voulu est bien appliqu�e. Par exemple, $a & $b == true applique d'abord l'�galit�, et ensuite le et logique, alors que ($a & $b) == true applique d'abord le et logique, puis l'�galit�.
Prenez garde aux transtypages. Si les deux param�tres, de chaque cot� de l'op�rateur, sont des cha�nes, l'op�rateur de bit va op�rer sur les valeurs ASCII des cha�nes.
Le rapport d'erreur de PHP utilise des champs de bits,
qui sont une illustration de l'extinction des bits.
Pour afficher les erreurs, sauf les notices, les
instructions du php.ini sont :
E_ALL & ~E_NOTICE
Cela se comprend en comparant avec E_ALL : 00000000000000000111011111111111 Puis en �teignant la valeur de E_NOTICE... 00000000000000000000000000001000 ... et en l'inversant via ~: 11111111111111111111111111110111 Finalement, on utilise le ET logique (&) pour lire les bits activ�s dans les deux valeurs : 00000000000000000111011111110111
Un autre moyen d'arriver � ce r�sultat est d'utiliser
le OU exclusif (^), qui cherche
les bits qui ne sont activ�s que dans l'une ou l'autre des
valeurs, exclusivement :
E_ALL ^ E_NOTICE
error_reporting peut aussi �tre utilis� pour
illustrer l'activation de buts. Pour afficher
uniquement les erreurs et les erreurs recouvrables,
on utilise :
E_ERROR | E_RECOVERABLE_ERROR
Cette approche combine E_ERROR 00000000000000000000000000000001 et E_RECOVERABLE_ERROR 00000000000000000001000000000000 Avec l'op�rateur OR (|) pour s'assurer que les bits sont activ�s dans l'une ou l'autre valeur : 00000000000000000001000000000001
Exemple #1 Op�rations sur les bits et les entiers
<?php
/*
* Ignorez cette partie,
* c'est juste du formatage pour clarifier les r�sultats
*/
$format = '(%1$2d = %1$04b) = (%2$2d = %2$04b)'
. ' %3$s (%4$2d = %4$04b)' . "\n";
echo <<<EOH
--------- --------- -- ---------
resultat valeur test
--------- --------- -- ---------
EOH;
/*
* Voici les exemples
*/
$values = array(0, 1, 2, 4, 8);
$test = 1 + 4;
echo "\n Bitwise AND \n";
foreach ($values as $value) {
$result = $value & $test;
printf($format, $result, $value, '&', $test);
}
echo "\n Bitwise Inclusive OR \n";
foreach ($values as $value) {
$result = $value | $test;
printf($format, $result, $value, '|', $test);
}
echo "\n Bitwise Exclusive OR (XOR) \n";
foreach ($values as $value) {
$result = $value ^ $test;
printf($format, $result, $value, '^', $test);
}
?>
L'exemple ci-dessus va afficher :
--------- --------- -- --------- resultat valeur test --------- --------- -- --------- Bitwise AND ( 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) Bitwise Inclusive OR ( 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) Bitwise Exclusive OR (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)
Exemple #2 Op�ration sur les bits et les cha�nes
<?php
echo 12 ^ 9; // Affiche '5'
echo "12" ^ "9"; // Affiche le caract�re d'effacement (ascii 8)
// ('1' (ascii 49)) ^ ('9' (ascii 57)) = #8
echo "hallo" ^ "hello"; // Affiche les valeurs ASCII #0 #4 #0 #0 #0
// 'a' ^ 'e' = #4
echo 2 ^ "3"; // Affiche 1
// 2 ^ ((int)"3") == 1
echo "2" ^ 3; // Affiche 1
// ((int)"2") ^ 3 == 1
?>
Exemple #3 D�calage de bits sur les entiers
<?php
/*
* Voici quelques exemples
*/
echo "\n--- D�calages � droite sur des entiers positifs ---\n";
$val = 4;
$places = 1;
$res = $val >> $places;
p($res, $val, '>>', $places, 'copie du bit de signe maintenant � gauche');
$val = 4;
$places = 2;
$res = $val >> $places;
p($res, $val, '>>', $places);
$val = 4;
$places = 3;
$res = $val >> $places;
p($res, $val, '>>', $places, 'des bits sont sortis par la droite');
$val = 4;
$places = 4;
$res = $val >> $places;
p($res, $val, '>>', $places, 'm�me r�sultat que ci-dessus : pas de d�calage au dela de 0');
echo "\n--- D�calages � droite sur des entiers n�gatifs ---\n";
$val = -4;
$places = 1;
$res = $val >> $places;
p($res, $val, '>>', $places, 'copie du bit de signe maintenant � gauche');
$val = -4;
$places = 2;
$res = $val >> $places;
p($res, $val, '>>', $places, 'des bits sont sortis par la droite');
$val = -4;
$places = 3;
$res = $val >> $places;
p($res, $val, '>>', $places, 'm�me r�sultat que ci-dessus : pas de d�calage au dela de -1');
echo "\n--- D�calages � gauche sur des entiers positifs ---\n";
$val = 4;
$places = 1;
$res = $val << $places;
p($res, $val, '<<', $places, 'compl�ment de z�ros � droite');
$val = 4;
$places = (PHP_INT_SIZE * 8) - 4;
$res = $val << $places;
p($res, $val, '<<', $places);
$val = 4;
$places = (PHP_INT_SIZE * 8) - 3;
$res = $val << $places;
p($res, $val, '<<', $places, 'les bits de signe sont sortis');
$val = 4;
$places = (PHP_INT_SIZE * 8) - 2;
$res = $val << $places;
p($res, $val, '<<', $places, 'les bits de signe sont sortis � gauche);
echo "\n--- D�calages � gauche sur des entiers n�gatifs ---\n";
$val = -4;
$places = 1;
$res = $val << $places;
p($res, $val, '<<', $places, 'compl�ment de z�ros � droite');
$val = -4;
$places = (PHP_INT_SIZE * 8) - 3;
$res = $val << $places;
p($res, $val, '<<', $places);
$val = -4;
$places = (PHP_INT_SIZE * 8) - 2;
$res = $val << $places;
p($res, $val, '<<', $places, 'les bits de signe sont sortis � gauche, y compris le bit de signe');
/*
* Ignorez cette section
* Elle contient du code pour le formatage de cet exemple
*/
function p($res, $val, $op, $places, $note = '') {
$format = '%0' . (PHP_INT_SIZE * 8) . "b\n";
printf("Expression : %d = %d %s %d\n", $res, $val, $op, $places);
echo " D�cimal :\n";
printf(" val=%d\n", $val);
printf(" res=%d\n", $res);
echo " Binaire :\n";
printf(' val=' . $format, $val);
printf(' res=' . $format, $res);
if ($note) {
echo " Note : $note\n";
}
echo "\n";
}
?>
R�sultat de l'exemple ci-dessus sur une machine 32 bits :
--- D�calages � droite sur des entiers positifs --- Expression : 2 = 4 >> 1 D�cimal : val=4 res=2 Binaire : val=00000000000000000000000000000100 res=00000000000000000000000000000010 Note : copie du bit de signe maintenant � gauche Expression : 1 = 4 >> 2 D�cimal : val=4 res=1 Binaire : val=00000000000000000000000000000100 res=00000000000000000000000000000001 Expression : 0 = 4 >> 3 D�cimal : val=4 res=0 Binaire : val=00000000000000000000000000000100 res=00000000000000000000000000000000 Note : des bits sont sortis par la droite Expression : 0 = 4 >> 4 D�cimal : val=4 res=0 Binaire : val=00000000000000000000000000000100 res=00000000000000000000000000000000 Note : m�me r�sultat que ci-dessus : pas de d�calage au dela de 0 --- D�calages � droite sur des entiers n�gatifs --- Expression : -2 = -4 >> 1 D�cimal : val=-4 res=-2 Binaire : val=11111111111111111111111111111100 res=11111111111111111111111111111110 Note : copie du bit de signe maintenant � gauche Expression : -1 = -4 >> 2 D�cimal : val=-4 res=-1 Binaire : val=11111111111111111111111111111100 res=11111111111111111111111111111111 Note : des bits sont sortis par la droite Expression : -1 = -4 >> 3 D�cimal : val=-4 res=-1 Binaire : val=11111111111111111111111111111100 res=11111111111111111111111111111111 Note : m�me r�sultat que ci-dessus : pas de d�calage au dela de -1 --- D�calages � gauche sur des entiers positifs --- Expression : 8 = 4 << 1 D�cimal : val=4 res=8 Binaire : val=00000000000000000000000000000100 res=00000000000000000000000000001000 Note : compl�ment de z�ros � droite Expression : 1073741824 = 4 << 28 D�cimal : val=4 res=1073741824 Binaire : val=00000000000000000000000000000100 res=01000000000000000000000000000000 Expression : -2147483648 = 4 << 29 D�cimal : val=4 res=-2147483648 Binaire : val=00000000000000000000000000000100 res=10000000000000000000000000000000 Note : les bits de signe sont sortis Expression : 0 = 4 << 30 D�cimal : val=4 res=0 Binaire : val=00000000000000000000000000000100 res=00000000000000000000000000000000 Note : bits shift out left side --- D�calages � gauche sur des entiers n�gatifs --- Expression : -8 = -4 << 1 D�cimal : val=-4 res=-8 Binaire : val=11111111111111111111111111111100 res=11111111111111111111111111111000 Note : compl�ment de z�ros � droite Expression : -2147483648 = -4 << 29 D�cimal : val=-4 res=-2147483648 Binaire : val=11111111111111111111111111111100 res=10000000000000000000000000000000 Expression : 0 = -4 << 30 D�cimal : val=-4 res=0 Binaire : val=11111111111111111111111111111100 res=00000000000000000000000000000000 Note : bits shift out left side, including sign bit
R�sultat de l'exemple ci-dessus sur une machine 64 bits :
--- BIT SHIFT RIGHT ON POSITIVE INTEGERS --- Expression : 2 = 4 >> 1 D�cimal : val=4 res=2 Binaire : val=0000000000000000000000000000000000000000000000000000000000000100 res=0000000000000000000000000000000000000000000000000000000000000010 Note : copie du bit de signe maintenant � gauche Expression : 1 = 4 >> 2 D�cimal : val=4 res=1 Binaire : val=0000000000000000000000000000000000000000000000000000000000000100 res=0000000000000000000000000000000000000000000000000000000000000001 Expression : 0 = 4 >> 3 D�cimal : val=4 res=0 Binaire : val=0000000000000000000000000000000000000000000000000000000000000100 res=0000000000000000000000000000000000000000000000000000000000000000 Note : des bits sont sortis par la droite Expression : 0 = 4 >> 4 D�cimal : val=4 res=0 Binaire : val=0000000000000000000000000000000000000000000000000000000000000100 res=0000000000000000000000000000000000000000000000000000000000000000 Note : m�me r�sultat que ci-dessus : pas de d�calage au dela de 0 --- BIT SHIFT RIGHT ON NEGATIVE INTEGERS --- Expression : -2 = -4 >> 1 D�cimal : val=-4 res=-2 Binaire : val=1111111111111111111111111111111111111111111111111111111111111100 res=1111111111111111111111111111111111111111111111111111111111111110 Note : copie du bit de signe maintenant � gauche Expression : -1 = -4 >> 2 D�cimal : val=-4 res=-1 Binaire : val=1111111111111111111111111111111111111111111111111111111111111100 res=1111111111111111111111111111111111111111111111111111111111111111 Note : des bits sont sortis par la droite Expression : -1 = -4 >> 3 D�cimal : val=-4 res=-1 Binaire : val=1111111111111111111111111111111111111111111111111111111111111100 res=1111111111111111111111111111111111111111111111111111111111111111 Note : m�me r�sultat que ci-dessus : pas de d�calage au dela de -1 --- D�calage � gauche sur les entiers n�gatifs --- Expression : 8 = 4 << 1 D�cimal : val=4 res=8 Binaire : val=0000000000000000000000000000000000000000000000000000000000000100 res=0000000000000000000000000000000000000000000000000000000000001000 Note : compl�ment de z�ros � droite Expression : 4611686018427387904 = 4 << 60 D�cimal : val=4 res=4611686018427387904 Binaire : val=0000000000000000000000000000000000000000000000000000000000000100 res=0100000000000000000000000000000000000000000000000000000000000000 Expression : -9223372036854775808 = 4 << 61 D�cimal : val=4 res=-9223372036854775808 Binaire : val=0000000000000000000000000000000000000000000000000000000000000100 res=1000000000000000000000000000000000000000000000000000000000000000 Note : les bits de signe sont sortis Expression : 0 = 4 << 62 D�cimal : val=4 res=0 Binaire : val=0000000000000000000000000000000000000000000000000000000000000100 res=0000000000000000000000000000000000000000000000000000000000000000 Note : bits shift out left side --- D�calage � gauche sur les entiers n�gatifs --- Expression : -8 = -4 << 1 D�cimal : val=-4 res=-8 Binaire : val=1111111111111111111111111111111111111111111111111111111111111100 res=1111111111111111111111111111111111111111111111111111111111111000 Note : compl�ment de z�ros � droite Expression : -9223372036854775808 = -4 << 61 D�cimal : val=-4 res=-9223372036854775808 Binaire : val=1111111111111111111111111111111111111111111111111111111111111100 res=1000000000000000000000000000000000000000000000000000000000000000 Expression : 0 = -4 << 62 D�cimal : val=-4 res=0 Binaire : val=1111111111111111111111111111111111111111111111111111111111111100 res=0000000000000000000000000000000000000000000000000000000000000000 Note : bits shift out left side, including sign bit
N'effectuez pas de d�calage � droite de plus de 32 bits sur les syst�mes 32 bits. N'effectuez pas de d�calage � droite dans le cas o� le r�sultat est un nombre plus long que 32 bits. Utilisez les fonctions de l'extension gmp pour les manipulations sur les bits, lorsque les entiers d�passent PHP_INT_MAX.
Voyez aussi pack(), unpack(), gmp_and(), gmp_or(), gmp_xor(), gmp_testbit(), gmp_clrbit()