你可能对“击败”这个词很熟悉。如果没有,让我们来了解一下:) 位是计算机中信息的最小计量单位。它的名字来源于英文“ binary digital ”——“二进制数”。一位可以表示为两个数字之一:1 或 0。有一个基于 1 和 0 的特殊数字系统 - 二进制。我们不会深入数学丛林,只是注意到 Java 中的任何数字都可以转换为其二进制形式。为此,您需要使用包装类。 例如,以下是对数字执行此操作的方法
所有操作均从左到右执行,但要考虑到它们的优先级。例如,如果我们写:
int
:
public class Main {
public static void main(String[] args) {
int x = 342;
System.out.println(Integer.toBinaryString(x));
}
}
控制台输出:
101010110
1010 10110(为了便于阅读,我添加了一个空格)是二进制数 342。我们实际上已将这个数字分成单独的位 - 零和一。通过它们,我们可以执行称为按位的运算。
-
~
— 按位“非”运算符。
00000000 00000000 00000001 01010110
- java 中 int 类型变量中的数字 342 11111111 11111111 11111110 10101001
- java 中表达式 ~342 的结果 让我们尝试在实践中这样做:
public class Main {
public static void main(String[] args) {
int x = 342;
System.out.println(Integer.toBinaryString(~x));
}
}
控制台输出:
11111111111111111111111010101001
-
&
— 按位运算符“AND”
&&
)非常相似。&&
正如您所记得的,true
仅当两个操作数都为 true 时,运算符才会返回。按位的&
工作方式类似:它逐位比较两个数字。比较的结果是第三个数字。例如,我们以数字 277 和 432 为例: 100010101 - 二进制形式的数字 277 110110000 - 二进制形式的数字 432 接下来,运算符将&
较高数字的第一位与较低数字的第一位进行比较。由于这是一个“AND”运算符,因此仅当两个位都等于 1 时,结果才等于 1。在所有其他情况下,结果将为 0。 100010101 &
110110000 _______________ 100010000 - 工作结果&
我们首先比较第一位两个数字彼此的组合,然后是第二位,第三位,依此类推。正如您所看到的,只有在两种情况下,数字中的两个位都等于 1(第一位和第五位)。其他所有比较的结果都是0。因此,最终我们得到了数字100010000。在十进制中,它对应于数字272。我们来检查一下:
public class Main {
public static void main(String[] args) {
System.out.println(277&432);
}
}
控制台输出:
272
|
- 按位“或”。操作原理是相同的——我们逐位比较两个数字。只有现在,如果至少一位等于 1,结果就等于 1。让我们看一下相同的数字 - 277 和 432:
|
110110000 _______________ 110110101 - 工作结果。|
这里的结果是不同的:只有那些在两个数字中都为零的位仍然为零。运算结果是数字 110110101。在十进制中,它对应于数字 437。让我们检查一下:
public class Main {
public static void main(String[] args) {
System.out.println(277|432);
}
}
控制台输出:
437
我们计算的一切都正确!:)
^
- 按位异或(也称为 XOR)
true
如果至少一个操作数为真,则普通的“或”返回。但不一定是其中之一——如果两者都存在的话true
——那就是结果true
。true
但仅当其中一个操作数为 true 时,异或才返回。如果两个操作数都为 true,则将返回常规“or” true
(“至少有一个为 true”),但独占 or 将返回false
。这就是为什么它被称为独家。知道了前面按位运算的原理,你大概可以轻松地自己执行277^432运算了。但让我们更好地再次一起弄清楚:) 100010101 ^
110110000 _______________ 010100101 - 工作结果^
这是我们的结果。两个数字中相同的位返回 0(“其中之一”公式不起作用)。但那些0-1或1-0的组合最终变成了一个整体。结果我们得到了数字010100101,在十进制中,它对应的是数字165。我们来看看我们计算是否正确:
public class Main {
public static void main(String[] args) {
System.out.println(277^432);
}
}
控制台输出:
165
极好的!一切都与我们想象的完全一样:) 现在是时候熟悉称为位移位的操作了。原则上,这个名字本身就说明了一切。我们将获取一些数字并左右移动它的位:)让我们看看它是什么样的:
左移
位左移由符号表示 示例<<
:
public class Main {
public static void main(String[] args) {
int x = 64;//meaning
int y = 3;//quantity
int z = (x << y);
System.out.println(Integer.toBinaryString(x));
System.out.println(Integer.toBinaryString(z));
}
}
在此示例中,数字x=64
称为值。我们将移动的是它的位。我们将位左移(这可以通过符号的方向来确定<<
) 在二进制系统中,数字 64 = 1000000 这个数字y=3
称为数量。Quantity 回答了“数字的位应该向右/向左移动多少位x
?”的问题,在我们的示例中,我们将它们向左移动 3 位。为了让换档过程更加清晰,我们来看一张图。在我们的示例中,我们使用 int 类型的数字。Int
占用32位计算机内存。这就是我们原来的数字 64 的样子: 现在,从字面意义上来说,我们将每个位向左移动 3 个单元: 这就是我们得到的。正如您所看到的,我们所有的位都已移位,并且从范围之外添加了 3 个零。3 - 因为我们移动了 3。如果我们移动了 10,就会添加 10 个零。因此,该表达式的x << y
意思是“将 y 个单元格的位х
向左移动”。我们的表达式的结果是数字 1000000000,在十进制中等于 512。让我们检查一下:
public class Main {
public static void main(String[] args) {
int x = 64;//meaning
int y = 3;//quantity
int z = (x << y);
System.out.println(z);
}
}
控制台输出:
512
这是正确的!理论上,位可以无限地移位。但由于我们有编号int
,因此只有 32 个可用单元。其中,7 个已被数字 64(1,000,000)占用。因此,例如,如果我们向左移动 27 次,我们唯一的单位将超出范围并“覆盖”。只剩下零!
public class Main {
public static void main(String[] args) {
int x = 64;//meaning
int y = 26;//quantity
int z = (x << y);
System.out.println(z);
}
}
控制台输出:
0
正如我们所料,这个超出了 32 位单元并消失了。我们得到了一个仅由零组成的 32 位数字。 当然,在十进制中它对应于 0。记住左移的一个简单规则:每左移一次,数字就乘以 2。例如,让我们尝试计算没有位图片的表达式的结果。 111111111 << 3
我们需要将数字 111111111 乘以 2 三倍,结果是 888888888,我们来编写代码并检查一下:
public class Main {
public static void main(String[] args) {
System.out.println(111111111 << 3);
}
}
控制台输出:
888888888
右移
它们由符号 表示>>
。他们做同样的事情,只是方向不同!:) 我们不要重新发明轮子,而是尝试使用相同的数字 int 64 来完成此操作。
public class Main {
public static void main(String[] args) {
int x = 64;//meaning
int y = 2;//quantity
int z = (x >> y);
System.out.println(z);
}
}
由于右移 2,我们的数字的两个极端零超出了范围并被删除。我们得到数字 10000,在十进制中对应于数字 16。输出到控制台:
16
记住右移的一个简单规则:每个右移除以二,丢弃任何余数。例如, 35 >> 2
这意味着我们需要将35除以2 2次,丢弃余数 35/2 = 17
(丢弃余数1) 17:2 = 8
(丢弃余数1)总计35 >> 2
应该等于8。检查:
public class Main {
public static void main(String[] args) {
System.out.println(35 >> 2);
}
}
控制台输出:
8
Java中操作的优先级
当您编写或阅读代码时,您经常会遇到同时执行多个操作的表达式。了解它们的执行顺序非常重要,否则结果可能会出乎意料。由于Java中有很多操作,所以它们都被分成一个特殊的表:运算符优先级
运营商 | 优先级 |
---|---|
后缀 | expr++ expr-- |
一元 | ++expr --expr +expr ~ ! |
乘法 | * / % |
添加剂 | + - |
转移 | << >> >>> |
关系型的 | < > <= >= 实例化 |
平等 | == != |
按位与 | & |
按位异或 | ^ |
按位或 | | |
逻辑与 | && |
逻辑或 | || |
三元 | ? : |
任务 | = += -= *= /= %= &= ^= |= <<= >>= >>>= |
int x = 6 - 4/2;
首先将执行除法运算(4/2)。虽然她排在第二位,但她的优先级更高。圆括号或方括号将任何优先级更改为最大。你可能还记得学校里的这件事。例如,如果将它们添加到表达式中: int x = (6 - 4)/2;
将首先执行减法,因为它是在括号中计算的。&&
从表中可以看出,逻辑运算符的优先级相当低。因此,大多数情况下它会最后执行。例如: boolean x = 6 - 4/2 > 3 && 12*12 <= 119;
该表达式将像这样执行:
-
4/2 = 2
boolean x = 6 - 2 > 3 && 12*12 <= 119;
-
12*12 = 144
boolean x = 6 - 2 > 3 && 144 <= 119;
-
6-2 = 4
boolean x = 4 > 3 && 144 <= 119;
-
接下来将执行比较运算符:
4 > 3 = true
boolean x = true && 144 <= 119;
-
144 <= 119 = false
boolean x = true && false;
-
最后,将执行最后一个运算符
&&
。boolean x = true && false;
boolean x = false;
例如,加法运算符 (
+
) 的优先级高于比较运算符!=
(“不等于”);因此在表达式中:
boolean x = 7 != 6+1;
首先执行运算 6+1,然后检查 7!=7 (false),最后将结果赋给
false
变量x
。分配通常在所有操作中具有最低优先级 - 请查看表。
- 逻辑运算符- 关于逻辑运算的 JavaRush 讲座。我们不会很快看到它们,但你现在可以阅读它们,不会有任何伤害
GO TO FULL VERSION