我想详细了解这个 Java 程序的工作原理?我们为什么要这样做,我们如何利用这些价值观来解决这个问题?

时间:2021-05-25 03:17:22

标签: java byte shift signed

class shift_right {
    public static void main(String args[]) {
        char hex[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
        byte b = (byte) 0xf1;

        System.out.println("b = 0x" + hex[(b >> 4) & 0x0f] + hex[b & 0x0f]);
    }
}

我无法理解这里发生了什么

System.out.println("b = 0x" + hex[(b >> 4) & 0x0f] + hex[b & 0x0f]);

为什么要使用 0xf1 和 0x0f。

1 个答案:

答案 0 :(得分:1)

就像我在评论中所说的那样,您似乎没有清楚地了解位操作的工作原理以及如何使用它们。我的建议是做一些关于按位运算的练习,这样你就知道如何使用它们。不过,我会检查这段代码在做什么?

这段代码在做什么?

此代码将存储在变量 b 中的字节转换为十六进制形式。十六进制数组只允许我们将十进制转换为十六进制形式。这更像是一个中间步骤。

二进制转十进制?

假设我们有字节 1010 1010。要将其转换为十六进制,我们可以参考二进制转十六进制表

Binary to Hex

我们知道 1010 1010A A,可以写成 0xAA

此代码如何工作?

从上面的转换我们知道,我们可以直接将4位转换成16进制。代码也在做同样的事情。然而,我们面临的问题是我们如何准确地将一个二进制数一次转换为 4 位十六进制数。

这是按位运算发挥作用的地方。它们使我们能够相对轻松地进行切片、清除、设置、切换等操作。假设我们有一个十六进制 1000 1010

我们要转换

1010 -> A

1000 -> 8

按位 AND 可以让我们清除特定位置的位。如果您与 1 位 AND ,则它保持不变。但是,如果您将其与 0 相加。这些位将被清除。

第 1 步:转换 1010

1000 1010
0000 1111 (0x0F)
---------
0000 1010 <- the MSB 4 bits are now cleared. This will allow us to convert the 1010 to hex easily

1010 是十进制的 10,数组中的第十个元素是“A”。所以 hex[10] 给出 A。

第 2 步:转换 1000

如果我们只是用 0xF0 做一些明智的 AND 操作。我们得到的值是 1000 0000,它是 -127,而不是 8。我们需要以某种方式将其写入 0000 1000,即 8。这就是向右移动的用武之地。

1000 1010 >> 4
---------
1111 1000 <- result of shifting 4 times

现在,您可能想知道到底发生了什么。为什么不是移动4次0000 1000的结果?

当位右移时,有符号位被扩展并取代被移位的位。这称为 Arithmetic Shift,它发生在有符号字节上,而不是 Logical Shift 发生在无符号字节上。如果前导位为 0,则算术移位与逻辑移位非常相似。因此,现在要清除导致符号扩展的所有位,我们需要将数字与 0x0F 进行 AND 运算

1111 1000
0000 1111 (0x0F)
---------
0000 1000 This is 8 in decimal and hex[8] gives us '8'

所以最后我们得到 "0x" + "8" + "A",即 "0x8A"

相关问题