JavaRush /Java 博客 /Random-ZH /Java 中的逻辑运算符

Java 中的逻辑运算符

已在 Random-ZH 群组中发布
Java 中的逻辑运算。 Java 中的位运算 - 1

Java中的逻辑运算

逻辑运算是使用布尔运算符执行的。请原谅我的同义反复,但事情确实就是这样。基本逻辑运算(在编程和数学中)可以应用于逻辑参数(操作数),也可以用于形成更复杂的表达式,类似于数字的算术运算。例如表达式:

(a | b) | (c < 100) & !(true) ^ (q == 5)
是一个具有四个操作数的复杂逻辑表达式: (a | b),其中аb是类型变量boolean (c < 100) (true) (q == 5) 。反过来,简单逻辑表达式(a | b)也由两个操作数参数组成。 逻辑操作数是一个可以说是 true 或 false、truefalse的表达式。在 Java 术语中,布尔操作数是类型或布尔值的表达式boolean,例如:
  • (2 < 1)— 逻辑操作数,其值为false
  • true- 其值显然为true 的逻辑操作数
  • boolean a- 也可以是逻辑操作数,如布尔值 a
  • int a = 2-不是逻辑操作数,它只是类型变量int
  • String a = "true"也不是逻辑操作数。这是一个文本值为 的字符串"true"
Java 中有以下逻辑运算:
  • 逻辑否定,也称为NOT反转。在Java中,是用!操作数前的“ ”符号来表示的。适用于一个操作数。
  • 逻辑 and,它也是AND一个连词。&由应用它的两个操作数之间的“ ”符号指示。
  • 逻辑或者在Java中,它也是- OR,它也是析取。在Java中,用两个操作数之间的符号“ |”来表示。
  • 异或, XOR, 严格析取。在Java中,用两个操作数之间的符号“ ^”来表示。
  • 在 Java 中,逻辑运算符包括条件 or,表示为||,以及条件 and - &&
注意:在数理逻辑中,他们也考虑等价关系,换句话说,相等。但是,在 Java 中,等号运算符==不被视为逻辑运算符。 注意力!在 Java 中,逻辑运算符&,|^也适用于整数。在这种情况下,它们的工作方式略有不同,称为按位逻辑运算符。关于他们 - 在文章的末尾。让我们看一下表格,其中简要描述了每个 Java 逻辑运算符,下面我们将更详细地描述它们并提供代码示例。
Java运算符 姓名 类型 简短的介绍 例子
! 逻辑“非”(否定) 一元 !x意思是“不是x”。如果操作数为false,则返回true。如果操作数为true则返回false boolean x = true;
然后
// !x == false
& 逻辑与(AND,乘法) 二进制 如果两个操作数都为true则返回true a = true;
b = false;
然后
a & b == false
| 逻辑或(OR,加法) 二进制 如果至少有一个操作数为true ,则返回true a = true;
b = false;
然后
a | b == true
^ 逻辑异或 ( XOR) 二进制 如果一个且只有一个操作数为true ,则返回true。如果两个操作数均为truefalse则返回false。本质上,如果操作数不同,则返回true 。 a = true;
b = false;
然后
a ^ b == true
&& 条件 AND(短逻辑 AND) 二进制 与 相同,&但如果 左侧的操作数&false,则该运算符返回false而不检查第二个操作数。
|| 条件 OR(短逻辑 OR) 二进制 与 相同,|但如果左侧的运算符为true,则该运算符返回true而不检查第二个操作数。

JavaRush 课程中的逻辑运算

逻辑运算是不可避免的,在 JavaRush 课程中,逻辑运算从第一级开始就与条件和布尔数据类型一起出现。程序员逐渐学会使用数理逻辑的方法。为了通过逻辑结构进行更自信的操作,需要一定的灵活性和对某些过程的理解。因此,在多线程任务结束时,将在完全不同的级别上更详细地处理这些操作,此时大多数学生不再直接被语法和结构分散注意力,而是尝试深入研究任务的本质。

Java 中的逻辑运算。 Java 中的位运算 - 2

逻辑否定运算符!

该运算符是一元运算符,这意味着它适用于单个布尔表达式或操作数。它很容易理解,就像任何否定一样:运算符只是将表达式的含义更改为相反的含义。真值表或执行否定运算的结果:
!A
错误的 真的
真的 错误的
例子。逻辑非运算
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

   }
}
程序的输出如下:

false
true
false

逻辑 AND - &,以及条件 AND - &&

逻辑 AND 或合取应用于两个表达式,只有当两个操作数都为 true 时,其结果才为 true。也就是说,如果aor操作数之一bfalse ,则无论第二个运算符的值如何,表达式都a & b将为false 。如果您想象true是数字 1,false是 0,那么该运算符的工作&方式与常规乘法完全相同。因此,逻辑与通常被称为“逻辑乘法”。顺便说一句,这个事实有助于快速记住运算符的操作&,而不是将其与逻辑或运算符混淆|。真值表AND,也是运算符工作的结果&
A a&b
真的 真的 真的
真的 错误的 错误的
错误的 真的 错误的
错误的 错误的 错误的
逻辑AND,它也是一个连词,例子:
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
   }
}
程序结果:

false
true
false
false
该运算符&&有时称为“短 AND”。当使用逻辑操作数时,它会产生与运算符相同的结果&。然而,他的作品本身却存在着差异。因此,您已经注意到,如果a & b表达式 () 中的操作数afalse,则检查操作数的值就没有意义b:运算结果肯定为false。因此,如果我们根本不需要第二个操作数的值,那么使用它&&可以减少程序中的计算次数。如果我们将示例中的所有运算符替换&&&,结果将完全相同,但程序本身会运行得更快一些(尽管我们不会注意到这一点,因为我们正在谈论 mili-micro...简而言之,非常小的时间单位)。

逻辑或是运算符|,条件或是运算符||

Java 中的 OR 运算符用符号 表示|。逻辑或或析取应用于两个表达式,且仅当两个操作数都为假时,其结果将为假。在这里,我们在某种程度上观察到与运算符 的情况相同的情况&,但恰恰相反。也就是说,如果至少一个操作数为true ,则无论第二个运算符的值如何,表达式a | b都保证为true 。如果&它的行为类似于逻辑乘法,那么 OR 就是逻辑加法,如果您想象true为 1,false为 0。请记住,逻辑加法的工作方式与普通加法不同。在这种情况下,1 + 1 不等于 2,而是等于 1(数字 2 在该系统中根本不存在)。有时析取被理解为 0 和 1 中的最大值,在这种情况下,如果至少一个操作数等于 1 ( true ),我们就得到完全true。OR 真值表,也称为运算符的结果|
A 一个 | 乙
真的 真的 真的
真的 错误的 真的
错误的 真的 真的
错误的 错误的 错误的
逻辑或,也称为析取,例如:
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);

   }
}
结果:

false
true
true
true
如果我们使用条件 OR 运算符 -||而不是|,我们将得到完全相同的结果,但是,与条件 AND 的情况一样&&,它会经济地运行:如果我们“遇到”第一个操作数等于true,则不检查第二个操作数,但结果立即为true

XOR Java - 逻辑异或 - 运算符 ^

XOR、模2加法、逻辑异或、逻辑减法、严格析取、按位补……运算符^在布尔代数中有很多名字。如果操作数不同,则将此运算符应用于两个操作数,结果将为true ;如果操作数相同,则结果为false 。因此,用减去零( false)和减去一(true )来比较它是很方便的。真值表XOR,也称为运算符的结果^
布尔值 布尔值b ^b
真的 真的 错误的
真的 错误的 真的
错误的 真的 真的
错误的 错误的 错误的
例子:
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);
   }
}
结果:

false
false
true
true

逻辑运算的优先级

就像在数学中一样,在编程中,当运算符出现在同一表达式中时,它们具有特定的执行顺序。一元运算符比二元运算符有优势,乘法(甚至逻辑)比加法有优势。我们将逻辑运算符排列在列表中越高,它们的优先级就越高:
  1. !
  2. &
  3. ^
  4. |
  5. &&
  6. ||
让我们看一下例子。连词和析取 ( &and |) 具有不同的优先级:
public class Solution {
   public static void main(String[] args) {
       boolean a = true, b = true, c = false;
       System.out.println(a | b & c);
}
如果我们从左到右进行操作,即先应用运算符|,然后应用 - &,我们将得到值false。但事实上,如果您运行该程序,您将确定输出将为true,因为逻辑 AND 运算符&将比逻辑 OR 运算符具有更高的优先级|。为了避免混淆,您需要记住什么&行为类似于乘法,|什么行为类似于加法。您可以更改优先顺序。只需使用括号,就像学校数学一样。让我们稍微改变一下示例代码:
public class Solution {
   public static void main(String[] args) {
       boolean a = true, b = true, c = false;
       System.out.println((a|b)&c);
}
这是怎么回事?首先我们在括号中使用逻辑加法,然后使用乘法。结果将是错误的

复杂的逻辑表达式

当然,我们可以将布尔表达式和运算符结合起来。让我们记住文章开头的那句话:
(a | b) | (c < 100) & !(true) ^ (q == 5)
现在看起来没那么可怕了。a让我们编写一个程序来显示其值,之前已经确定了、bс的值q。计算复杂布尔表达式的值的示例
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));
   }
}
笔记:q我们的变量是类型int,但这q == 5是一个布尔表达式,并且它等于false,因为上面我们用q数字 2 进行了初始化。变量 也是如此c。该数字等于 25,但 (c < 100) 是一个等于true的布尔表达式。该程序的结果:

true
复杂的布尔表达式可用于测试非常复杂和分支条件,但不应过度使用它们:它们会使代码难以阅读。

按位(bitwise)运算符

在文章开头,我们提到运算符 &,|^可以与 Java 整数类型相关。在这种情况下,它们是按位运算符。它们也称为按位,因为一位数就是一位,并且这些运算专门针对位进行。当然,它们的工作方式与逻辑运算符有些不同,要准确理解它们的工作方式,您需要知道什么是二进制数字系统。如果你对此一无所知或者完全忘记了,我们建议你先阅读《Java:位和字节》一文,并提醒大家,在二进制数系统中只有两位数——0和1,所有数据在计算机中使用条件零和一来精确表示。我们习惯的任何数字(十进制;对于它们来说,有从 0 到 9 的 10 个不同的数字,我们可以用它们来书写任何数字)可以用二进制数字系统来表示。您可以使用数字系统基数 (2) 按顺序除法将十进制数转换为二进制数。每一步除法的余数以相反的顺序写出,将为我们提供所需的二进制数。例如,这里是将十进制数 103 转换为二进制表示形式: Java 中的逻辑运算。 Java 中的位运算 - 3

JavaRush 课程中的二进制数字系统

在 JavaRush 课程中,他们在学习多线程任务(第 10 级,讲座 1)时谈论二进制数字系统;讲座结束后有几个需要巩固的任务。然而,这个主题一点也不困难,即使您在课程中还没有学到那么深,您也可能会弄清楚。

除了,之外&,Java 还使用按位运算符: |^
  • ~ 按位求反运算符
  • >>按位右移
  • >>>无符号按位右移
  • <<按位左移
对于初学者来说,按位运算符似乎非常令人困惑和不自然。除了解决教育问题之外,他们通常不明白自己需要做什么。事实上,它们至少可以用来组织有效的除法和乘法,专业人士使用它们进行编码/解码、加密和生成随机数。

位运算符 &, | 和^

让我们看一下这些运算符如何工作的示例。假设我们有两个整数:
int a = 25;
int b = 112; 
我们需要对它们进行三个操作&|并将^结果显示在屏幕上。这是程序代码:
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);

   }
}
程序运行结果如下:

a & b = 16
a | b = 121
a ^ b = 105
如果你不明白发生了什么,结果就会看起来非常非常神秘。事实上,一切都比看起来简单。位运算符“看到”二进制形式的操作数。然后他们将逻辑运算符或&应用于两个数字的相应数字(位)。因此,对于数字 25 的二进制表示形式的最后一位,逻辑上与数字 112 的二进制表示形式的最后一位相加,即倒数第二位与倒数第二位,依此类推: 相同的逻辑可以在和的情况。 |^&Java 中的逻辑运算。 Java 中的位运算 - 4|^Java 中的逻辑运算。 Java 中的位运算 - 5

向左或向右位移位

Java 中有多种移位运算符。最常用的运算符<<是 和>>。它们分别将数字的二进制表示向左或向右移动,在向右移动的情况下,同时保留符号(我们将在下面解释保留符号的含义)。还有另一个右移运算符>>>。它做同样的事情,但>>不保存标志。那么,让我们用一个例子来看看他们的工作。 int a = 13 a << 1将数字 a 的二进制表示形式的所有位向左移动 1 位。为了简单起见,我们将数字 13 想象成二进制的 0000 1101。事实上,这个数字看起来像这样:00000000 00000000 00000000 00001101,因为 Javaint为数字分配了 4 个字节或 32 位。然而,这在示例中不起作用,因此在本示例中我们将认为我们的数字是一字节。 Java 中的逻辑运算。 Java 中的位运算 - 6右侧空出的位用零填充。此操作的结果是,我们得到数字 26。 a << 2它将数字的二进制表示形式的所有位a向左移动 2 位,右侧空出的两位用零填充。结果,我们将得到数字 52。 a << 3结果将是 104...注意到这个模式了吗?按位a左移 n 个位置就像将数字a乘以 2 的 n 次方。这同样适用于负数。这-13 << 3将给出结果-104。 a >> n将数字的二进制表示向右移动 n 位。例如,13 >> 1 将数字 1101 转换为数字 0110,即 6。13 >> 2结果将是 3。也就是说,本质上,这里我们将数字除以 2 的 n 次方,其中 n 是移位次数向右,但有一个警告:如果数字是奇数,在此操作期间我们似乎重置了数字的最后一位。但对于消极的情况则有所不同。比方说,如果您要求程序执行一项操作,请尝试检查程序将产生什么结果-13 >> 1。您将看到数字 -7,而不是您想象的 -6。发生这种情况是由于 Java 和其他编程语言中负数的存储方式所致。它们存储在所谓的互补代码中。在这种情况下,最高有效数字(左边的数字)在符号下方给出。如果是负数,则最高位为 1。

附加代码

我们来考虑一下这个数字int a = 13。如果在程序中使用命令将其二进制表示打印到控制台System.out.println(Integer.toBinaryString(a));,那么我们将得到 1101。事实上,这是一种速记符号,因为类型编号int在内存中占用 4 个字节,因此计算机“看到”的更多像这样:

00000000 00000000 00000000 00001101
最高有效数字为零,这意味着我们有一个正数。要转换为附加代码:
  1. 我们把数字-13写成所谓的“直接代码”。为此,请将数字的最高有效位更改为 1。
    操作结果:

    
    10000000 0000000 0000000 00001101
  2. 接下来,我们反转除符号位之外的所有位(将 0 更改为 1,将 1 更改为 0)。事实上,我们已经改变了。
    行动结果:

    
    11111111 11111111 11111111 11110010

    (是的,步骤 1 和步骤 2 可以合并,但最好这样想)

  3. 将所得数字加 1。
    操作结果:

    
    11111111 11111111 11111111 11110011
生成的二进制数是 -13,以二进制补码形式写入,位移位(和其他操作)将专门应用于它。只是并不是所有操作中操作逻辑上的差异都是明显的。假设,对于同样的左移,差异是不明显的;我们可以像处理正数一样处理负数。现在让我们向右移动-13 >> 1。由于我们的运算符>>保留了符号,因此在此操作中,左侧释放的所有位都不是用零填充,而是用 1 填充。因此,移动数字

11111111 11111111 11111111 11110011
向右移动一位,产生以下位序列:

11111111 11111111 11111111 11111001
如果我们将这个数字转换为直接代码(即先减 1,然后反转除第一个之外的所有位),我们会得到这个数字:

10000000 00000000 00000000 00000111
或-7。现在我们已经了解了符号保留右移运算符,它与运算符 的区别就会变得清楚>>>a >>> n— 此操作是无符号移位,也就是说,它将数字的二进制表示形式a向右移动 n 位,但不会像运算符 那样用 1 填充左侧空出的 n 位>>,而是用 0 填充。我们来做手术吧-13 >>> 1-13我们已经有了二进制补码的 数字:

11111111 11111111 11111111 11110011
通过右移 1 位并用零填充空闲位,我们得到以下数字:

01111111 11111111 11111111 11111001
什么给出了十进制数2147483641

按位求反运算符 ~

这个一元运算符的工作原理非常简单:它反转整数的二进制表示的每一位。让我们看一下数字-13

11111111 11111111 11111111 11110011
按位求反运算~13将简单地反转每个位的值。结果我们得到:

00000000 00000000 00000000 00001100
12十进制形式。

简要结论

  • 所有逻辑运算符都适用于布尔表达式,即那些可以说是truefalse 的表达式。
  • 如果运算符&,|^应用于数字,我们就不再讨论逻辑运算,而是讨论按位运算。即,将两个数字都转换为二进制系统,并对这些数字逐位进行逻辑加法、乘法或减法运算。
  • 在数理逻辑中,运​​算符&|对应于合取和析取。
  • 逻辑 AND 类似于将 1 ( true ) 和 0 ( false ) 相乘。
  • 逻辑或类似于查找 1 ( true ) 和 0 ( false ) 中的最大值。
  • 对于整数 a 的按位求反,使用运算符~a
  • 要对布尔表达式 a 进行逻辑求反,请使用运算符!a
  • 负数以二进制补码形式存储和处理。
  • 按位右移可能会>>也可能不会保留符号 ( >>>)。
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION