JavaRush /Java 博客 /Random-ZH /Java 运算符简介:逻辑、算术、按位

Java 运算符简介:逻辑、算术、按位

已在 Random-ZH 群组中发布
我们来谈谈Java中的运算:数值、逻辑、位。这是学习如何编程绝对需要的理论基础。 Java 运算符简介:逻辑、算术、按位 - 1

Java中的运算符有哪些类型?

对于任何操作,我们至少需要两件事:
  • 操作员;
  • 操作数。
运算符的一个示例是两个数字相加运算中的简单加号。在这种情况下,相互相加的数字将成为操作数。因此,在运算符的帮助下,我们对一个或多个操作数进行运算。对两个操作数执行运算的运算符称为二元运算符。例如,将两个数字相加。对单个操作数执行运算的运算符称为一元运算符。例如,一元减号。

JavaRush 课程中的 Java 运算符

有几个讲座专门讨论第一个任务的第四级Java 运算符- Java 语法。特别是条件运算符,例如 boolean。本课程包含 22 个任务,帮助您了解比较运算符、条件运算符和逻辑运算符的工作原理。

Java中的数字运算

程序员对数字执行的最常见操作是将数值分配给变量。她和接线员一样,=你也很熟悉:
int a = 1;
int b = 2;
int c = 3;
还有算术运算。它们是使用二元算术运算符执行的:
表 1. 二元算术运算符
Java 运算符简介:逻辑、算术、按位 - 2前四个运算符不应引起任何问题:一切都与数学中的相同。最后一个运算符,即除法的余数,也不会做任何太复杂的事情。例如,如果我们将 24 除以 7,我们会得到 3 个整数和 3 个余数。该运算符将返回余数:
System.out.println(24 % 7); // prints 3
以下是来自 Oracle 官方文档站点的示例: Java 运算符简介:逻辑、算术、按位 - 3该程序将输出以下内容: 1 + 2 = 3 3 - 1 = 2 2 * 2 = 4 4 / 2 = 2 2 + 8 = 10 10 % 7 = 3 Java 允许您组合:例如,运算符赋值和算术运算符。让我们看一个例子:
int x = 0;
x = x + 1; // x = 0 + 1 => x = 1
x = x + 1; // x = 1 + 1 => x = 2
x = x + 1; // x = 2 + 1 => x = 3
这里我们定义了一个变量x并为其分配了零值。x接下来,在每一行中,我们为变量的当前值与 1 之和分配一个值x。每行的注释里都有解释。此过程称为变量增长或递增。上例中的递增操作可以使用运算符组合替换为类似的操作:
int x = 0;
x += 1; // x = 0 + 1 => x = 1
x += 1; // x = 1 + 1 => x = 2
x += 1; // x = 2 + 1 => x = 3
您可以将赋值运算符与任何算术运算符结合使用:
int x = 0;
x += 10; // x = 0 + 10 => x = 10
x -= 5; // x = 10 - 5 => x = 5
x *= 5; // x = 5 * 5 => x = 25
x /= 5; // x = 25 / 5 => x = 5
x %= 3; // x = 5 % 3 => x = 2;
让我们演示一下最后一个示例的工作原理:
Java 运算符简介:逻辑、算术、按位 - 4
除了二元运算符之外,Java 还有一元算术运算符。
表 2. 一元算术运算符:
Java 运算符简介:逻辑、算术、按位 - 4一元加号和减号的示例:
int x = 0;
x = (+5) + (+15); // Parentheses for clarity, it is possible without them
System.out.println("x = " + x);

int y = -x;
System.out.println("y = " + y);
Java 运算符简介:逻辑、算术、按位 - 6
自增和自减操作本质上很简单。在第一种情况下,变量增加 1,在第二种情况下,变量减少 1。示例如下:
int x = 9;
x++;
System.out.println(x); // 10

int y = 21;
y--;
System.out.println(y); // 20
这些操作有两种类型 - 后缀和前缀。在第一种情况下,运算符写在变量之后,在第二种情况下,运算符写在变量之前。唯一的区别在于何时执行递增或递减操作。示例和说明如下表所示。假设我们有一个变量:
int a = 2;
然后:
表 3. 递增-递减运算符:
Java 运算符简介:逻辑、算术、按位 - 5示范:
Java 运算符简介:逻辑、算术、按位 - 8
除了算术运算之外,还有(两个数字的)比较运算。结果始终为 true 或 false ( true / false )。
表 4. 比较运算符
Java 运算符简介:逻辑、算术、按位 - 9例子:
int a = 1;
int b = 2;

boolean comparisonResult = a == b;
System.out.println("a == b :" + comparisonResult);

comparisonResult = a != b;
System.out.println("a != b :" + comparisonResult);

comparisonResult = a > b;
System.out.println("a >  b :" + comparisonResult);

comparisonResult = a >= b;
System.out.println("a >= b :" + comparisonResult);

comparisonResult = a < b;
System.out.println("a <  b :" + comparisonResult);

comparisonResult = a <= b;
System.out.println("a <= b :" + comparisonResult);
示范:
Java 运算符简介:逻辑、算术、按位 - 10

Java中的逻辑运算

让我们看一下它们各自的逻辑运算和真值表:
  • 取反运算 ( NOT);
  • 并运算,逻辑与 ( AND);
  • 或运算,逻辑或 ( OR);
  • 模加运算,异或 ( XOR)。
否定运算符是一元运算符,适用于单个操作数。所有其他操作都是二进制的。让我们考虑一下这些操作的真值表。这里0相当于Java 中的false1相当于true
表 5. 否定运算符真值表 (NOT)
Java 运算符简介:逻辑、算术、按位 - 7
表 6. 合取运算符 (AND) 的真值表
Java 运算符简介:逻辑、算术、按位 - 8
表 7. 或运算符 (OR) 的真值表
Java 运算符简介:逻辑、算术、按位 - 9
表 8. 模加运算符 (XOR) 的真值表
Java 运算符简介:逻辑、算术、按位 - 10Java也有同样的逻辑运算:
  • !— 否定运算符;
  • &&— 逻辑 AND 运算符(短);
  • ||— 逻辑或运算符(短);
  • &——按位与运算符;
  • |— 按位或运算符;
  • ^— 按位异或运算符。
下面让我们进一步看看按位运算符和速记运算符之间的区别,同时让我们将所有真值表转换为 Java 代码:
public class LogicDemo {

   public static void main(String[] args) {
    notExample();
    andExample();
    orExample();
    xorExample();
   }

   public static void notExample() {
    System.out.println("NOT EXAMPLE:");
    System.out.println("NOT false = " + !false);
       System.out.println("NOT true  = " + !true);
    System.out.println();
   }

   public static void andExample() {
    System.out.println("AND EXAMPLE:");
    System.out.println("false AND false = " + (false & false));
    System.out.println("false AND true  = " + (false & true));
    System.out.println("true  AND false = " + (true & false));
    System.out.println("true  AND true  = " + (true & true));
    System.out.println();
   }

   public static void orExample() {
    System.out.println("OR EXAMPLE:");
    System.out.println("false OR false = " + (false | false));
    System.out.println("false OR true  = " + (false | true));
    System.out.println("true  OR false = " + (true | false));
     System.out.println("true  OR true  = " + (true | true));
    System.out.println();
   }

   public static void xorExample() {
    System.out.println("XOR EXAMPLE:");
    System.out.println("false XOR false = " + (false ^ false));
    System.out.println("false XOR true  = " + (false ^ true));
    System.out.println("true  XOR false = " + (true ^ false));
    System.out.println("true  XOR true  = " + (true ^ true));
    System.out.println();
   }
}
该程序将显示: NOT Examples: NOT false = true NOT true = false AND Examples: false AND false = false false AND true = false true AND false = false true AND true = true OR Examples: false OR false = false false OR true = true true OR false = true true OR true = true XOR 示例: false XOR false = false false XOR true = true true XOR false = true true XOR true = false 逻辑运算符仅适用于boolean变量。在我们的例子中,我们将它们直接应用于值,但您也可以将它们与boolean变量一起使用:
Java 运算符简介:逻辑、算术、按位 - 15
以及boolean表达式:
Java 运算符简介:逻辑、算术、按位 - 16
现在,我们有简写运算符 ( &&, ||) 和类似的按位运算符 ( &, |)。它们之间有什么区别?首先,按位可以应用于整数。我们稍后再讨论这个问题。其次,有些是缩写的,而另一些则不是。要了解缩写是什么样子,让我们看一下表达式:

false AND x = ?
true OR x = ?
x可以采用任何布尔值。而且一般来说,根据逻辑和真值表的规律,无论真假x 第一个表达式的结果将为,而第二个表达式的结果将为。看。
Java 运算符简介:逻辑、算术、按位 - 17
有时可以根据第一个操作数计算表达式的结果。&&这就是缩写运算符和的区别||。在与上述类似的表达式中,它们不计算第二个操作数的值。这是一个小例子:
Java 运算符简介:逻辑、算术、按位 - 18
对于简写运算符,不计算表达式的第二部分。但只有当表达式的结果从第一个操作数中已经显而易见时,才会发生这种情况。

Java中的位运算

好了,我们来到了最有趣的部分:按位运算。顾名思义,这些是对位执行的操作。但在我们深入讨论这个主题之前,有必要先讨论一下相关领域。

二进制数字系统中数字的表示

数字与程序中的任何其他信息一样,以二进制代码存储在计算机内存中。二进制代码是一组零和一。每个零或一代表一个称为比特的信息单元。

根据维基百科:

位(来自英文binary digital——二进制数;也是一个文字游戏:英文bit——片、粒子)是信息量的计量单位。1 位信息是一种符号或信号,可以具有两种含义:开或关、是或否、高或低、带电或不带电;在二进制系统中它是 1(一)或 0(零)。

按位运算符处理什么类型的数据?

Java 中的位运算仅对整数执行。整数作为一组位存储在计算机内存中。我们可以说计算机将任何信息转换为二进制数字系统(一组位),然后才与其交互。但是二进制数字系统是如何工作的呢?在十进制中,我们只有 10 个符号:0、1、2、3、4、5、6、7、8、9。我们使用这些符号来计数。9 之后是 10,19 - 20 之后,99 - 100 之后,749 - 750 之后。也就是说,我们使用可用的 10 个符号的组合,可以使用它们来计数“从零到午餐”。在二进制数字系统中,不是十个符号,而是只有两个 - 0、1。但是,按照与十进制系统中相同的原理将这些符号组合起来,我们就可以无限计数。
让我们演示一下十进制和二进制从 0 到 15 的计数:
Java 运算符简介:逻辑、算术、按位 - 11正如你所看到的,一切并没有那么复杂。除了位之外,还有其他熟悉的信息单位——字节千字节兆字节千兆字节等。您可能知道1 个字节有 8 个位。这是什么意思?这意味着一行8位占用1个字节。以下是字节的示例:

00000000 - 1 byte
10110010 - 1 byte
01011011 - 1 byte
一个字节中可能的非重复位组合数量为 256 (2 8 = 256)。但让我们回到 Java。有这样一种整数数据类型—— byte。这种类型可以取-128到127之间的值,并且计算机内存中的一个数字正好占用8位,即1个字节。1 个此类数字正好占用 1 个byte计算机内存。这里的名字重合并非偶然。我们记得,1 个字节可以存储 256 个不同的值。一种类型的数字byte可以呈现 256 个不同的值(128 个负值、127 个正值和 1 个零)。每个数字值byte都有一组唯一的八位。不仅 type 是这种情况byte,所有整型类型也是如此。给出的类型byte作为最小的示例。下表显示了所有 Java 整数类型及其占用的内存空间: Java 运算符简介:逻辑、算术、按位 - 12考虑类型int。它可以存储 2147483648 个负值、2147483647 个正值和 1 个零。全部的:

2147483648 + 2147483647 + 1 = 4294967296.
该类型在计算机内存中占用 32 位。一组 32 个 0 和 1 的可能组合数为:
232 = 4294967296.
与该类型可以容纳的值的数量相同int。这只是演示了一种数据类型的取值范围与其大小(内存中的位数)之间的关系。Java中任何类型的任何数字都可以转换为二进制。让我们看看使用 Java 语言可以多么轻松地完成此操作。我们将从 type 的例子中学习int。这种类型有它自己的包装类 - Integer。他有一个toBinaryString,可以为我们完成所有工作:
Java 运算符简介:逻辑、算术、按位 - 21
瞧 - 没那么复杂。但仍有一些事情需要澄清。int该数字需要 32 位。但是,当我们在上面的示例中打印数字 10 时,我们在控制台中看到 1010,这是因为没有打印前导零。如果显示它们,我们将在控制台中看到 000000000000000000000000000001010,而不是 1010。但为了易于理解,所有前导零都被省略。没那么难,直到你问自己:负数怎么样?它只感知二进制系统中的信息。原来减号也需要写成二进制码。这可以使用直接代码或补充代码来完成。

直接代码

一种在二进制数系统中表示数字的方法,其中最高有效位(最左边的位)分配给数字的符号。如果数字是正数,则最左边的位写入 0,如果是负数,则写入 1。
让我们以 8 位数字为例来看看:
Java 运算符简介:逻辑、算术、按位 - 13该方法很简单,原则上也容易理解。然而,它也有缺点:执行数学运算困难。例如,负数和正数相加。除非进行额外的操作,否则它们无法折叠。

附加代码

通过使用附加代码,您可以避免直接代码的缺点。有一个简单的算法可以获取数字的附加代码。让我们尝试获取数字-5 的附加代码。让我们用二进制数系统中的补码来表示这个数字。步骤 1. 我们使用直接代码获得负数的表示。对于 -5,则为 10000101。 步骤 2. 反转除符号数字之外的所有数字。让我们将所有零替换为 1,并将除了最左边的位之外的所有位置都替换为 0。

10000101 => 11111010
步骤 3. 将结果值加一:

11111010 + 1 = 11111011
准备好。我们使用二进制补码得到了二进制数系统中-5 的值。这对于理解以下内容非常重要,因为 Java 使用二进制补码来以位形式存储负数。

位运算的类型

现在我们已经完成了所有的介绍,让我们来谈谈Java中的按位运算。对整数执行按位运算,其结果是整数。在此过程中,数字被转换为二进制,对每一位执行运算,然后结果被转换回十进制。操作列表如下表所示: Java 运算符简介:逻辑、算术、按位 - 14正如我们已经发现的,数字可以表示为一组位。按位运算精确地对这种表示的每一位执行运算。让我们来NOTANDORXOR。回想一下,我们最近只查看了逻辑操作数的真值表。在这种情况下,相同的操作应用于整数的每一位。

按位一元运算符 NOT ~

该运算符将所有零替换为 1,并将所有 1 替换为零。假设我们有十进制数 10。在二进制中,这个数字是 1010。如果我们对这个数字应用一元按位求反运算符,我们会得到如下结果: Java 运算符简介:逻辑、算术、按位 - 15让我们看看它在 Java 代码中的样子:
public static void main(String[] args) {
   int a = 10;

   System.out.println(" a = " + a + "; binary string: " + Integer.toBinaryString(a));
   System.out.println("~a = " + ~a + "; binary string: " + Integer.toBinaryString(~a));
}
现在让我们看看控制台中显示的内容:
Java 运算符简介:逻辑、算术、按位 - 25
在第一行中,我们获得了不带前导零的二进制数字系统中的值。尽管我们看不到它们,但它们就在那里。第二行证明了这一点,其中所有位都转换为相反的位。这就是为什么我们看到这么多领先单位。这些是以前的前导零,在第一行打印时被编译器忽略。这是一个小程序,为了清晰起见,它还显示前导零。
Java 运算符简介:逻辑、算术、按位 - 26

按位与运算符

该运算符适用于两个数字。AND它在每个数字的位之间执行操作。让我们看一个例子: Java 运算符简介:逻辑、算术、按位 - 16这个运算是对两个数字执行的。Java 代码中的示例:
Java 运算符简介:逻辑、算术、按位 - 28

按位或运算符

OR 适用于两个数字。它在每个数字的位之间执行 OR 运算: Java 运算符简介:逻辑、算术、按位 - 17现在让我们看看在 IDEA 中会是什么样子:
Java 运算符简介:逻辑、算术、按位 - 30

按位运算、异或(XOR)

让我们看一下相同的示例,但使用了新的操作: Java 运算符简介:逻辑、算术、按位 - 18示例代码:
Java 运算符简介:逻辑、算术、按位 - 32

按位左移

该运算符适用于两个操作数,即在运算中x << y,数字的位x会左移y。这是什么意思?我们看一下运算的例子,10 << 1 Java 运算符简介:逻辑、算术、按位 - 19运算的结果是十进制的20。从上图可以看出,所有位都左移 1。在此操作期间,最高有效位(最左边的位)的值会丢失。最低有效位(最右边的位)用零填充。对于这次手术你有什么想说的吗?
  1. 通过将数字的位向左移动X一位N,我们将该数字乘以X2 N

    这是一个例子:

    Java 运算符简介:逻辑、算术、按位 - 34
  2. 但!如果值为 1 的位占据最左边的位置,则数字的符号可能会改变。

  3. 如果无限左移,数字将简单地变为 0。让我们演示一下第 2 点和第 3 点:

    Java 运算符简介:逻辑、算术、按位 - 35

按位右移

该运算符适用于两个操作数。那些。在运算中x >> y,数字的位xy向右移动位置。让我们看另一个例子。我们来示意性地分析一下操作过程10 >> 1。让我们将数字 10 的所有位向右移动一位: Java 运算符简介:逻辑、算术、按位 - 20在移位操作期间,我们丢失了右边的位。他们就这样消失了。最左边的位是数字的符号(0 为正,1 为负)。因此,最终值中的位置与原始数字中的位置相同。以负数为例: Java 运算符简介:逻辑、算术、按位 - 21最右边的位丢失,最左边的位从原始数字复制而来,作为该数字的荣誉符号。如何在IDEA中完成这一切?原则上,没什么复杂的,只需拿走它并移动它:
Знакомство с операторами Java: логические, арифметические, побитовые - 38
现在。对于向右移动的数字你能说什么?它们可以被 2 整除。每次向右移动一位,我们将原始数字除以 2。如果该数字不能被 2 整除,结果将向负无穷大(向下)舍入。但这只有在我们将位精确移位 1 时才有效。如果移位 2 位,则除以 4。移位 3 位,则除以 8。移位 4 位,则除以 16。看到了吗?2 的幂...当我们将数字X向右移动N一位时,我们将该数字除以X2 的 2 次方N。示范:
public class BitOperationsDemo {

   public static void main(String[] args) {

    for (int i = 1; i <= 10; i++) {

        int shiftOperationResult = 2048 >> i;
        int devideOperationResult = 2048 / (int) Math.pow(2, i);


           System.out.println(shiftOperationResult + " - " + devideOperationResult);
    }

   }

}
这里发生了什么?
  1. 变量 i 从 1 递增到 10 的循环。

  2. 每次迭代我们计算 2 个值:
    • shiftOperationResult我们将数字 2048 右移 i 位的结果写入变量;

    • devideOperationResult我们将数字 2048 除以 2 的 i 次方的结果写入变量。

  3. 我们成对显示获得的两个值。

程序执行结果如下: 1024 - 1024 512 - 512 256 - 256 128 - 128 64 - 64 32 - 32 16 - 16 8 - 8 4 - 4 2 - 2

按位右移并补零

正常右移会保留数字的符号(最高有效位保留其值),而零填充右移则不会。并且最高有效位用零填充。让我们看看它是什么样子的: Знакомство с операторами Java: логические, арифметические, побитовые - 22

Java中操作的优先级

与数学一样,Java 也有运算优先级。下表显示了我们考虑的操作的优先级(从最高到最低)。 Знакомство с операторами Java: логические, арифметические, побитовые - 23

有用的使用示例

确定数字的奇偶性

Знакомство с операторами Java: логические, арифметические, побитовые - 24

查找数组中的最大元素

Знакомство с операторами Java: логические, арифметические, побитовые - 25要找到最小元素,只需更改正确位置的比较符号即可。
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION