- Opérateurs logiques en Java
- Opérateur de négation logique !
- ET logique - &, ainsi que ET conditionnel - &&
- Le OU logique est l'opérateur |, ainsi que le OU conditionnel est l'opérateur ||
- XOR - OU exclusif logique - opérateur ^
- Priorité des opérations logiques
- Expressions logiques complexes
- Opérateurs au niveau du bit (bit au niveau du bit)
- Opérateurs au niveau du bit &, | et ^
- Code supplémentaire
- Opérateur de négation au niveau du bit ~
Opérations logiques en Java
Les opérations logiques sont effectuées à l'aide d'opérateurs booléens. Pardonnez la tautologie, mais c’est exactement ainsi que les choses se passent. Les opérations logiques de base (en programmation et en mathématiques) peuvent être appliquées à des arguments logiques (opérandes) et peuvent également être utilisées pour former des expressions plus complexes, similaires aux opérations arithmétiques sur les nombres. Par exemple l'expression :
(a | b) | (c < 100) & !(true) ^ (q == 5)
est une expression logique complexe avec quatre opérandes : (a | b)
, où а
et b
sont des variables de type boolean
(c < 100)
(true)
(q == 5)
. À son tour, une expression logique simple (a | b)
se compose également de deux arguments d'opérande. Un opérande logique est une expression dont on peut dire qu'elle est vraie ou fausse, vraie ou fausse . Dans le langage Java, un opérande booléen est une expression de type boolean
ou booléen, par exemple :
(2 < 1)
— opérande logique, sa valeur est faussetrue
- un opérande logique dont la valeur est évidemment vraieboolean a
- peut aussi être un opérande logique, comme un booléen aint a = 2
- n'est pas un opérande logique , c'est juste une variable de typeint
String a = "true"
n'est pas non plus un opérande logique . Il s'agit d'une chaîne dont la valeur de texte est"true"
.
- Négation logique , également connue
NOT
sous le nom d'inversion. En Java, il est indiqué par le!
symbole « » devant l'opérande. S'applique à un opérande. - Logique et , c'est aussi
AND
une conjonction. Indiqué par un&
symbole « » entre les deux opérandes auxquels il est appliqué. - Logique ou en Java , c'est aussi -
OR
, c'est aussi disjonction. En Java, il est indiqué par le symbole «|
» entre deux opérandes. - Disjonction exclusive ou stricte
XOR
. En Java, il est indiqué par le symbole «^
» entre deux opérandes. - En Java, les opérateurs logiques incluent le conditionnel ou , noté
||
, ainsi que le conditionnel et -&&
.
==
n'est pas considéré comme un opérateur logique. Attention! En Java, les opérateurs logiques&
,|
et^
s'appliquent également aux entiers. Dans ce cas, ils fonctionnent légèrement différemment et sont appelés opérateurs logiques au niveau du bit (ou au niveau du bit). À leur sujet - vers la fin de l'article. Examinons un tableau avec une brève description de chacun des opérateurs logiques Java, et ci-dessous nous les décrirons plus en détail et fournirons des exemples de code.
Opérateur Java | Nom | Taper | Brève description | Exemple |
---|---|---|---|---|
! |
« non » logique (négation) | Unaire | !x signifie « pas x ». Renvoie true si l'opérande est false . Renvoie false si l'opérande est true . |
boolean x = true; Alors // !x == false |
& |
ET logique ( AND , multiplication) |
Binaire | Renvoie vrai si les deux opérandes sont vrais . | a = true; b = false; Alors a & b == false |
| |
OU logique ( OR , addition) |
Binaire | Renvoie true si au moins un des opérandes est true . | a = true; b = false; Alors a | b == true |
^ |
OU exclusif logique ( XOR ) |
Binaire | Renvoie true si un et un seul des opérandes est vrai . Renvoie false si les deux opérandes sont true ou false . Essentiellement, cela renvoie vrai si les opérandes sont différents. | a = true; b = false; Alors a ^ b == true |
&& |
ET conditionnel (ET logique court) | Binaire | Identique à , & mais si l'opérande à gauche de & est false , cet opérateur renvoie false sans vérifier le deuxième opérande. |
|
|| |
OU conditionnel (OU logique court) | Binaire | Identique à , | mais si l'opérateur de gauche est true , l'opérateur renvoie true sans vérifier le deuxième opérande. |
Opérateur de négation logique !
Cet opérateur est unaire, ce qui signifie qu'il s'applique à une seule expression ou opérande booléen. C'est très simple à comprendre, comme toute négation : l'opérateur change simplement le sens de l'expression en son contraire. Table de vérité ou résultats de l'exécution d'une opération de négation :La valeur d' un | !un |
FAUX | vrai |
vrai | FAUX |
public class Solution {
public static void main(String[] args) {
boolean a = true;
System.out.println(!a); // here our boolean expression reverses its value
System.out.println(!false); // non-false expression, as you might guess, will be equal to... what?
System.out.println(!(2 < 5)); // expression (2 < 5) is true, so its negation is false
}
}
Le résultat du programme sera le suivant :
false
true
false
ET logique - &, ainsi que ET conditionnel - &&
Le ET logique ou la conjonction est appliqué à deux expressions, et son résultat ne sera vrai que si les deux opérandes sont vrais. Autrement dit, si l'un des opérandesa
or b
est faux , alors l'expression a & b
sera fausse quelle que soit la valeur du deuxième opérateur. Si vous imaginez que vrai est le nombre 1 et faux est 0, alors l'opérateur &
fonctionne exactement de la même manière qu'une multiplication régulière. Par conséquent, le ET logique est souvent appelé « multiplication logique ». Et, en passant, ce fait permet de se souvenir rapidement du fonctionnement de l'opérateur &
et de ne pas le confondre avec l'opérateur logique ou |
. Table de vérité ET, c’est aussi le résultat du travail de l’opérateur&
un | b | un B |
vrai | vrai | vrai |
vrai | FAUX | FAUX |
FAUX | vrai | FAUX |
FAUX | FAUX | FAUX |
public class Solution {
public static void main(String[] args) {
boolean a = true;
boolean b = false;
boolean c = true;
System.out.println(a & b); // if we multiply true by false, we will definitely get false
System.out.println(a & c); // true to true will be true
System.out.println(false & (2 > 5));
System.out.println((2 < 5) & false);
// regardless of the truthfulness of the expression in brackets, in which case we have to be content with false
}
}
Résultat du programme :
false
true
false
false
L'opérateur &&
est parfois appelé « AND court ». Il produit le même résultat lorsque vous travaillez avec des opérandes logiques que l'opérateur &
. Il y a cependant une différence dans son travail lui-même. Ainsi, vous avez déjà remarqué que si a & b
l'opérande dans l'expression ( ) a
est faux , alors cela n'a aucun sens de vérifier la valeur de l'opérande b
: le résultat de l'opération sera définitivement faux . Donc si nous n’avons pas fondamentalement besoin de la valeur du deuxième opérande, en l’utilisant &&
nous réduisons le nombre de calculs dans le programme. Si nous remplaçons tous les opérateurs de l'exemple &
par &&
, le résultat sera exactement le même, mais le programme lui-même fonctionnera un peu plus vite (même si nous ne le remarquerons pas, puisqu'il s'agit de mili-micro... en bref , très petites unités de temps).
Le OU logique est l'opérateur |, ainsi que le OU conditionnel est l'opérateur ||
L'opérateur OR en Java est représenté par le symbole|
. Un OU logique ou une disjonction est appliqué à deux expressions, et son résultat sera faux si et seulement si les deux opérandes sont faux. Ici, nous observons dans une certaine mesure la même image que dans le cas de l'opérateur &
, mais exactement le contraire. Autrement dit, si au moins un opérande est vrai , alors l'expression a | b
est garantie vraie quelle que soit la valeur du deuxième opérateur. Si &
cela se comporte comme une multiplication logique, alors OU est une addition logique, si vous imaginez que vrai vaut 1 et faux vaut 0. N'oubliez pas que l'addition logique fonctionne différemment de l'addition normale. 1 + 1 dans ce cas n'est pas égal à 2, mais à 1 (le chiffre 2 n'existe tout simplement pas dans ce système). Parfois, la disjonction est comprise comme le maximum de 0 et 1, et dans ce cas, si au moins un opérande est égal à 1 ( true ), nous obtenons exactement true . Table de vérité OU, également appelée résultat de l'opérateur |
:
un | b | un | b |
vrai | vrai | vrai |
vrai | FAUX | vrai |
FAUX | vrai | vrai |
FAUX | FAUX | FAUX |
public class Solution {
public static void main(String[] args) {
boolean a = true;
boolean b = false;
boolean c = true;
System.out.println(!a | b); // Compose the use of two logical operators: a == true, so !a, as we already know, is false.
System.out.println(a | c);
System.out.println((2 < 5) | false); // expression (2 < 5) is true, which means that for any second operand we get a true result
System.out.println((2 > 5) | true);
}
}
Résultat:
false
true
true
true
Si nous utilisons l'opérateur conditionnel OR - ||
au lieu de |
, nous obtiendrons exactement le même résultat, mais, comme dans le cas du AND conditionnel &&
, il agira de manière économique : si nous « rencontrons » le premier opérande égal à true , la valeur de le deuxième opérande n'est pas vérifié, mais immédiatement le résultat est vrai .
XOR Java - OU exclusif logique - opérateur ^
XOR
, addition modulo 2, XOR logique, soustraction logique, disjonction stricte, complément au niveau du bit... l'opérateur ^
a de nombreux noms en algèbre booléenne. Le résultat de l'application de cet opérateur à deux opérandes sera vrai si les opérandes sont différents et faux si les opérandes sont identiques. Par conséquent, il est pratique de le comparer en soustrayant des zéros ( false ) et des uns ( true ). Table de vérité XOR
, également appelée résultat de l'opérateur^
:
Booléen un | Booléen b | un^b |
vrai | vrai | FAUX |
vrai | FAUX | vrai |
FAUX | vrai | vrai |
FAUX | FAUX | FAUX |
public class Solution {
public static void main(String[] args) {
boolean a = true;
boolean b = false;
boolean c = true;
System.out.println(!a ^ b); // Compose the use of two logical operators: a == true, so !a, as we already know, is false.
System.out.println(a ^ c);
System.out.println((2 < 5) ^ false);
System.out.println((2 > 5) ^ true);
}
}
Résultat:
false
false
true
true
Priorité des opérations logiques
Tout comme en mathématiques, en programmation, les opérateurs ont un ordre d’exécution spécifique lorsqu’ils apparaissent dans la même expression. Les opérateurs unaires ont des avantages par rapport aux opérateurs binaires et la multiplication (même logique) par rapport à l'addition. Nous avons classé les opérateurs logiques plus haut dans la liste, plus leur priorité est élevée :!
&
^
|
&&
||
&
et |
) ont des priorités différentes :
public class Solution {
public static void main(String[] args) {
boolean a = true, b = true, c = false;
System.out.println(a | b & c);
}
Si nous devions procéder de gauche à droite, c'est-à-dire appliquer d'abord l'opérateur |
puis - &
, nous obtiendrions la valeur false . Mais en fait, si vous exécutez ce programme, vous serez sûr que le résultat sera vrai , puisque l'opérateur logique AND &
aura une priorité plus élevée que l'opérateur logique OR |
. Pour éviter toute confusion, vous devez vous rappeler ce qui &
se comporte comme une multiplication et |
ce qui se comporte comme une addition. Vous pouvez modifier l'ordre de priorité. Utilisez simplement des parenthèses, comme en mathématiques à l’école. Modifions un peu notre exemple de code :
public class Solution {
public static void main(String[] args) {
boolean a = true, b = true, c = false;
System.out.println((a|b)&c);
}
Quoi de neuf? Nous utilisons d’abord l’addition logique entre parenthèses, puis la multiplication. Le résultat sera faux .
Expressions logiques complexes
Bien entendu, nous pouvons combiner des expressions booléennes et des opérateurs. Rappelons l'expression du début de l'article :(a | b) | (c < 100) & !(true) ^ (q == 5)
Maintenant, ça n'a plus l'air si effrayant. Écrivons un programme qui affiche sa valeur, après avoir préalablement déterminé les valeurs de a
, b
, с
et q
. Exemple de calcul de la valeur d'une expression booléenne complexe
public class Solution {
public static void main(String[] args) {
boolean a = true;
boolean b = false;
int c = 25;
int q = 2;
System.out.println((a|b) | (c < 100) & !(true)^(q == 5));
}
}
Note:q
notre variable est de type int
, mais q == 5
c'est une expression booléenne, et elle est égale à false , puisque ci-dessus nous avons initialisé avec q
le chiffre 2. Il en va de même avec la variable c
. Ce nombre est égal à 25, mais (c < 100) est une expression booléenne égale à true . Le résultat de ce programme :
true
Les expressions booléennes complexes peuvent être utilisées pour tester des conditions très complexes et ramifiées, mais il ne faut pas en abuser : elles rendent le code difficile à lire.
Opérateurs au niveau du bit (bit au niveau du bit)
Au début de l'article, nous avons mentionné que les opérateurs&
, |
et ^
peuvent être utilisés en relation avec les types entiers Java. Dans ce cas, ce sont des opérateurs au niveau du bit. On les appelle également au niveau du bit, car un chiffre équivaut à un bit et ces opérations fonctionnent spécifiquement avec des bits. Bien sûr, ils fonctionnent quelque peu différemment des opérateurs logiques, et pour comprendre exactement comment, vous devez savoir ce qu'est un système de nombres binaires. Si vous n'en savez rien ou si vous l'avez complètement oublié, nous vous suggérons de lire d'abord l'article Java : bits et octets , et de rappeler à tous que dans le système de nombres binaires, il n'y a que deux chiffres - 0 et 1, et toutes les données dans l'ordinateur est représenté avec précision en utilisant des zéros et des uns conditionnels. N'importe lequel des nombres auxquels nous sommes habitués (décimaux ; pour eux, il y a 10 chiffres différents de 0 à 9, avec lesquels nous écrivons n'importe quel nombre) peut être représenté dans le système de nombres binaires. Vous pouvez convertir un nombre décimal en binaire en utilisant la division séquentielle en colonne à l'aide de la base du système numérique (2). Les restes de la division à chaque étape, écrits dans l'ordre inverse, nous donneront le nombre binaire souhaité. Voici par exemple la conversion du nombre décimal 103 en représentation binaire :
Système de nombres binaires dans le cours JavaRush Dans le cours JavaRush, ils parlent du système de nombres binaires tout en étudiant la quête MultiThreading (niveau 10, cours 1) ; après le cours, il y a plusieurs tâches à consolider. Cependant, ce sujet n'est pas du tout difficile, et même si vous n'êtes pas encore allé aussi loin dans le cours, vous y arriverez probablement. |
&
, |
et ^
Java utilise également des opérateurs au niveau du bit :
~
opérateur de négation au niveau du bit>>
décalage au niveau du bit vers la droite>>>
décalage à droite au niveau du bit non signé<<
décalage au niveau du bit vers la gauche
Opérateurs au niveau du bit &, | et ^
Regardons un exemple du fonctionnement de ces opérateurs. Disons que nous avons deux entiers :int a = 25;
int b = 112;
Nous devons leur appliquer trois opérations et &
afficher le résultat à l’écran. Voici le code du programme : |
^
public class Solution {
public static void main(String[] args) {
int a = 25;
int b = 112;
int res1 = a & b;
int res2 = a | b;
int res3 = a ^ b;
System.out.println("a & b = " + res1);
System.out.println("a | b = " + res2);
System.out.println("a ^ b = " + res3);
}
}
Le résultat du programme est le suivant :
a & b = 16
a | b = 121
a ^ b = 105
Si vous ne comprenez pas ce qui se passe, le résultat semble très, très mystérieux. En fait, tout est plus simple qu’il n’y paraît. Les opérateurs au niveau du bit « voient » les numéros d'opérandes sous leur forme binaire. Et puis ils appliquent des opérateurs logiques &
, |
ou ^
aux chiffres (bits) correspondants des deux nombres. Ainsi, car &
le dernier bit de la représentation binaire du nombre 25 s'additionne logiquement au dernier bit de la représentation binaire du nombre 112, l'avant-dernier bit avec l'avant-dernier, et ainsi de suite : La même logique peut être tracée dans le cas de |
et ^
.
Décalage de bits vers la gauche ou la droite
Il existe plusieurs opérateurs de décalage de bits en Java. Les opérateurs les plus couramment utilisés<<
sont et >>
. Ils déplacent la représentation binaire d’un nombre respectivement vers la gauche ou la droite, et dans le cas d’un déplacement vers la droite, tout en préservant le signe (nous expliquerons ci-dessous ce que signifie conserver le signe). Il existe un autre opérateur de décalage à droite >>>
. Cela fait la même chose mais >>
ne sauvegarde pas le signe. Examinons donc leur travail à l'aide d'un exemple. int a = 13
a << 1
décale tous les bits de la représentation binaire du nombre a vers la gauche de 1 bit. Pour simplifier, imaginons le nombre 13 en binaire comme 0000 1101. En fait, ce nombre ressemble à ceci : 00000000 00000000 00000000 00001101, puisque Java int
alloue 4 octets ou 32 bits pour les nombres. Cependant, cela ne joue aucun rôle dans l'exemple, donc dans cet exemple, nous considérerons que notre nombre est d'un octet. Le bit libéré à droite est rempli de zéros. À la suite de cette opération, nous obtenons le nombre 26. a << 2
Elle décale tous les bits de la représentation binaire du nombre a
vers la gauche de 2 bits, et les deux bits libérés à droite sont remplis de zéros. En conséquence, nous obtiendrons le nombre 52. a << 3
Le résultat sera 104... Remarquez le modèle ? Le décalage au niveau du bit a
vers la gauche de n positions fonctionne comme multiplier un nombre a
par 2 à la puissance n. La même chose s'applique aux nombres négatifs. Cela -13 << 3
donnera le résultat -104. a >> n
décale la représentation binaire d’un nombre n positions vers la droite. Par exemple, 13 >> 1
transforme le nombre 1101 en nombre 0110, c'est-à-dire 6. Et 13 >> 2
le résultat sera 3. Autrement dit, en substance, nous divisons ici le nombre par 2 à la puissance n, où n est le nombre de changements à droite, mais avec une mise en garde : si le nombre est impair, lors de cette opération on semble réinitialiser le dernier bit du nombre. Mais avec les négatifs, la situation est quelque peu différente. Disons, essayons de vérifier ce que le programme produira si vous lui demandez d'effectuer une opération -13 >> 1
. Vous verrez le chiffre -7, et non -6, comme vous pourriez le penser. Cela est dû à la manière dont les nombres négatifs sont stockés dans Java et d’autres langages de programmation. Ils sont stockés dans ce qu'on appelle du code complémentaire. Dans ce cas, le chiffre le plus significatif (celui de gauche) est donné sous le signe. Dans le cas d’un nombre négatif, le chiffre le plus significatif est 1.
Code supplémentaire
Considérons le nombreint a = 13
. Si dans le programme vous imprimez sa représentation binaire sur la console à l'aide de la commande System.out.println(Integer.toBinaryString(a));
, alors nous obtiendrons 1101. En fait, il s'agit d'une notation abrégée, puisque le numéro de type int
occupe 4 octets en mémoire, donc l'ordinateur le « voit » davantage comme ça:
00000000 00000000 00000000 00001101
Le chiffre le plus significatif est zéro, ce qui signifie que nous avons un nombre positif. Pour convertir en code supplémentaire :
-
Nous écrivons le nombre -13 dans ce qu'on appelle le « code direct ». Pour ce faire, remplacez le chiffre le plus significatif du nombre par 1.
Résultat de l'action :10000000 0000000 0000000 00001101
-
Ensuite, on inverse tous les bits (on change 0 en 1 et 1 en 0) sauf le bit de signe. En fait, nous l'avons déjà modifié.
Résultat de l'action :11111111 11111111 11111111 11110010
(oui, les étapes 1 et 2 pourraient être combinées, mais il vaut mieux y penser ainsi)
- Ajoutez 1 au nombre obtenu.
Résultat de l'action :11111111 11111111 11111111 11110011
-13 >> 1
. Puisque notre opérateur >>
préserve le signe, dans cette opération tous les bits libérés à gauche sont remplis non pas de zéros, mais de uns. Ainsi, en déplaçant le nombre
11111111 11111111 11111111 11110011
un bit vers la droite, ce qui donne la séquence de bits suivante :
11111111 11111111 11111111 11111001
Si nous convertissons ce nombre en code direct (c'est-à-dire soustrayons d'abord 1, puis inversons tous les bits sauf le premier), nous obtenons le nombre :
10000000 00000000 00000000 00000111
ou -7. Maintenant que nous avons compris l'opérateur de décalage à droite préservant les signes, il deviendra clair en quoi il diffère de l'opérateur >>>
. a >>> n
— cette opération est un décalage non signé, c'est-à-dire qu'elle décale la représentation binaire d'un nombre a
vers la droite de n bits, mais remplit les n bits libérés à gauche non pas avec des uns, comme l'opérateur >>
, mais avec des zéros. Faisons l'opération -13 >>> 1
. Nous avons déjà le nombre -13
en complément à deux :
11111111 11111111 11111111 11110011
En décalant vers la droite d'1 bit et en remplissant le bit libre par zéro, on obtient le nombre suivant :
01111111 11111111 11111111 11111001
Ce qui donne le nombre en notation décimale 2147483641
.
Opérateur de négation au niveau du bit ~
Cet opérateur unaire fonctionne très simplement : il inverse chaque bit de la représentation binaire d'un entier. Prenons le numéro-13
:
11111111 11111111 11111111 11110011
L'opération de négation au niveau du bit ~13
inversera simplement la valeur de chaque bit. En conséquence nous obtenons :
00000000 00000000 00000000 00001100
Ou 12
sous forme décimale.
Brèves conclusions
- Tous les opérateurs logiques s'appliquent aux expressions booléennes, c'est-à-dire celles dont on peut dire qu'elles sont vraies ou fausses .
- Si les opérateurs
&
,|
ou^
sont appliqués à des nombres, on ne parle plus d'opérations logiques, mais d'opérations au niveau du bit. C'est-à-dire que les deux nombres sont convertis en système binaire et que les opérations d'addition logique, de multiplication ou de soustraction sont appliquées à ces nombres bit par bit. - En logique mathématique, les opérateurs
&
et|
correspondent à la conjonction et à la disjonction. - Le ET logique revient à multiplier 1 ( vrai ) et 0 ( faux ).
- Le OU logique revient à trouver le maximum entre 1 ( vrai ) et 0 ( faux ).
- Pour la négation au niveau du bit d'un entier a, l'opérateur est utilisé
~a
. - Pour nier logiquement une expression booléenne a, utilisez l'opérateur
!a
. - Les nombres négatifs sont stockés et traités dans le code complément à deux.
- Un décalage au niveau du bit vers la droite peut
>>
ou non conserver le signe (>>>
).
GO TO FULL VERSION