此代码段:
(x >>> 3) & ((1 << 5) - 1)
显然会产生一个 5 位整数,其中 3 - 7 位为x
.
您将如何理解这一点?
我们先来看看((1 << 5) - 1)
。
1 << 5
等于100000
二进制。11111
5 个 1 的二进制数。现在,重要的是要理解这a & 0b11111
是一个只保留a
. 回想一下,&
当且仅当两个位都为 1 时,两个位的 为 1。a
因此,第 5 位以上的任何位都将变为 0,因为bit & 0 == 0
。此外,从第 1 位到第 5 位的所有位都将保留其原始值,因为bit & 1 == bit
(0 & 1 == 0
和1 & 1 == 1
)。
现在,因为我们将 in 的位x
向下x >>> 3
移动 3,丢失了 的三个最低有效位x
,所以我们将上述过程应用于位 4 到 8(从索引 1 开始)。因此,操作的结果只保留那些位(如果我们说第一位是位 0,那么这确实是位 3 到位 7,如您所说)。
我们举个例子:1234
. 在二进制中,即10011010010
. 所以,我们从移位 3 开始:
10011010010 >>> 3 = 10011010
本质上,我们只是剪掉最后 3 位。现在我们可以执行&
操作了:
10011010
& 00011111
--------
00011010
所以,我们的最终结果是11010
。如您所见,结果如预期:
bits | 1 0 0 1 1 0 1 0 0 1 0
index | 10 9 8 7 6 5 4 3 2 1 0
^-------^
(x >>> 3)
逻辑右移x
3 位,即不在左侧进行符号扩展。低 3 位丢失。(这相当于无符号除以 8。)
1 << 5
左移1
5 位,即乘以 32,得到0b00000000000000000000000000100000.
-1
减去 1,得到 31,或0b00000000000000000000000000011111.
&
将这些与在一起,仅产生 的结果的低 5 位,x >>> 3
即原始的 3..7 位x.
“你将如何理解这一点?”。
我假设你实际上是在问你应该如何理解它。(不同于只是向你解释的人......)
理解它的方法是“手动执行”它。
拿一张纸和一支铅笔。
根据您对 Java 运算符优先级如何工作的理解,找出执行操作的顺序。
根据您对每个运算符的理解,将位的输入模式写在纸上,然后以正确的顺序“手动执行”每个操作……。
如果你用几个 的值多次这样做x
,你应该会理解为什么这个表达式给你一个 5 位的数字。
如果你对其他几个例子重复这个练习,你应该会达到不需要用铅笔和纸完成繁琐过程的地步。
我看到@arshajii 在这个例子中基本上已经为你做了这个。但我认为如果你自己做/重复这项工作,你会得到更深入的理解。
关于 Java 中的整数和按位运算要记住的一件事是,这些操作始终使用 32 位或 64 位操作执行……即使操作数是 8 位或 16 位。另一件要记住的事情(尽管在这里不相关)是移位运算符的右手操作数被切分为 5 位或 6 位,具体取决于这是 32 位还是 64 位操作。