« Les opérations bit à bit/Les prédicats de comparaison » : différence entre les versions

Contenu supprimé Contenu ajouté
Ligne 257 :
 
: <math> ( x \geq 0 ) - ( x \leq 0 )</math>
 
==Le prédicat d'inégalité des signes==
 
Déterminer si deux entiers ont des signes différents peut sembler trivial, mais vous n'aurez peut-être pas pensé que cela pouvait se faire avec une seule comparaison. Un code naïf pour résoudre ce problème devrait utiliser plusieurs comparaisons : une expression pour vérifier si la première variable est positive et l'autre négative (deux comparaisons), et une autre expression pour vérifier l'inverse (deux comparaisons, encore). Le code qui correspond serait le suivant :
 
<syntaxhighlight lang="c">
int SignUnequals (int a , int b)
{
return ( a >= 0 && b < 0 ) || ( a < 0 && b >= 0 );
}
</syntaxhighlight>
 
Ou bien avec 3 comparaisons :
<syntaxhighlight lang="c">
int SignUnequals (int a , int b)
{
return ( a < 0 ) != ( b < 0 ); // Ou encore ( a >= 0 ) != ( b >= 0 )
}
</syntaxhighlight>
 
Mais l'opération XOR permet de faire cette vérification en une seule comparaison. Pour comprendre pourquoi, il faut rappeler que le bit de poids fort donne le signe du nombre, peu importe la représentation des nombres utilisée. Cela fonctionne non seulement en signe-magnitude, mais aussi en complément à 1 ou à 2. Lorsque l'on fait un XOR entre deux nombres, les deux "bits de signe" seront XORés, comme tous les autres bits. Or, l'opération XOR renvoie un 1 si les deux bits sont différents et un 0 s'ils sont égaux ! Ainsi, après avoir XORé les deux nombres, le bit de poids fort dira si les deux bits de signe étaient égaux ou non. Il faudra juste comparer sa valeur avec 1 et/ou 0. Pour cela, on pourrait penser utiliser le code suivant :
 
<syntaxhighlight lang="c">
int SignUnequals (int a , int b)
{
return ((a ^ b) >> 31) & 1 ;
}
</syntaxhighlight>
 
Mais il y a plus simple encore : on peut déduire le signe du résultat (et donc la valeur du bit de signe) en comparant avec 0 ! Si le résultat a pour bit de signe 1, il est négatif, donc inférieur à 0. Si ce bit de signe vaut 0, le résultat est supérieur ou égal à 0. On peut donc remplacer la sélection du bit de signe assez simplement par une comparaison avec 0. Ce qui donne le code suivant :
 
<syntaxhighlight lang="c">
int SignUnequals (int a , int b)
{
return (a ^ b) < 0 ;
}
</syntaxhighlight>
 
 
{{NavChapitre | book=Les opérations bit à bit