最近我一直在学习按位运算符,一路上有这个代码使用AND(&)按位运算符找到十进制数的二进制数字,代码如下:
byte b = -34;
for(int t = 128;t > 0; t = t/2)
{
if((b & t) != 0)System.out.println("1 ");
else System.out.println("0 ");
System.out.println("b & t yields: " + (b & t));
}
我修改了代码以显示在每次迭代期间由b& t计算的值。我想了解这段代码背后的确切机制,为什么它能找到二进制数字,请解释为什么b与每次迭代的t比较以及为什么t除以每次迭代2次?
此外,我想知道如何通过列出二进制数字手动计算(b& t)。我确实了解如何&但是当我列出34和128的二进制数字并对它们进行比较时:
1 0 0 0 0 0 0 0(128)
0 0 1 0 0 0 1 0(34) //I am unsure if the negative sign should be included
---------------
0 0 0 0 0 0 0 0
我得到的结果是0,但程序返回128这是令人费解的。
下面我还将包括执行程序的结果:
1
b & t yields: 128
1
b & t yields: 64
0
b & t yields: 0
1
b & t yields: 16
1
b & t yields: 8
1
b & t yields: 4
1
b & t yields: 2
0
b & t yields: 0
非常需要帮助:)
答案 0 :(得分:2)
将t
除以2
向右移位:
1 0 0 0 0 0 0 0 128 = t
0 1 0 0 0 0 0 0 64 = t / 2
0 0 1 0 0 0 0 0 32 = t / 2 / 2
...
t
始终将一位设置为1
,其他所有位均为0
。
然后使用&
将其与b进行比较。当且仅当两个输入中的相应位也是1
时,每个结果位为1
。
这意味着我们基本上检查b
- 位是1
的位置t
中的位是1
。这是从左到右的所有位完成的。
答案 1 :(得分:0)
由于存在两个问题: (1)OP困惑于他的手工计算与程序代码不匹配的原因,并且 (2)OP想知道为什么将其中一个变量除以2。
我只是结合答案: (1)负数表示为二进制补码。因此负34是
0 0 1 0 0 0 1 0 <-- +34
1 1 0 1 1 1 0 1 <-- one's complement of 34
1 1 0 1 1 1 1 0 <-- two's complement of 34
注意:二进制补码就是二进制补码+ 1。
(2)除以2的是向右移动(如果为二进制)。这就是循环中第三次输出零的原因(128中唯一的1与-34中的第三个零进行“与”运算)。