Op�rateurs sur les bits

Les op�rateurs sur les bits vous permettent de manipuler les bits dans un entier.

Les op�rateurs sur les bits
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(01248);
$test 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 "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 � gauchey 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

Avertissement

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()