【问题标题】:Could someone explain to me what the following Java code is doing?有人可以向我解释以下 Java 代码在做什么吗?
【发布时间】:2010-11-08 02:01:21
【问题描述】:
byte s[] = getByteArray()
for(.....)
Integer.toHexString((0x000000ff & s[i]) | 0xffffff00).substring(6);

我了解到您正在尝试将字节转换为十六进制字符串。我不明白这是怎么做到的。例如,如果 s[i] 是 00000001(十进制 1),您能否解释一下:

  1. 为什么是 0x000000ff & 00000001 ?为什么不直接使用 00000001?
  2. 为什么是#1 | 0xffffff00?
  3. 最后为什么要应用 substring(6)?

谢谢。

【问题讨论】:

    标签: java binary hex bit-manipulation


    【解决方案1】:

    这基本上是因为字节是用 Java 签名的。如果你将一个字节提升为一个 int,它将符号扩展,这意味着字节 0xf2 将变为 0xfffffff2。符号扩展是一种在扩展时保持值相同的方法,方法是将最高有效(符号)位复制到所有高阶位中。以上两个值都是-14,采用二进制补码表示法。相反,如果您将0xf2 扩大到0x000000f2,那么它将是242,可能不是你想要的。

    所以& 操作是去除这些扩展位中的任何一个,只留下最低有效的 8 位。但是,由于无论如何您都将在下一步中将这些位强制为 1,因此这一步似乎有点浪费。

    随后的 | 操作将强制所有这些高位为 1,这样您就可以保证从 ffffff00ffffffff (包括 toHexString 不给出前导零,它会将7 转换为"7",而不是您想要的"07"

    然后应用substring(6),这样您就只能得到这八个十六进制数字中的最后两个。

    当您可以使用String.format ("%02x", s[i]) 时,确保您得到一个两个字符的十六进制字符串似乎是一种非常复杂的方法。但是,当引入 String.format 时,这种特殊的 sn-p 代码可能早于 Java 5。


    如果你运行以下程序:

    public class testprog {
        public static void compare (String s1, String s2) {
            if (!s1.equals(s2))
                System.out.println ("Different: " + s1 + " " + s2);
        }
        public static void main(String args[]) {
            byte b = -128;
            while (b < 127) {
                compare (
                    Integer.toHexString((0x000000ff & b) | 0xffffff00).substring(6),
                    String.format("%02x", b, args));
                b++;
            }
            compare (
                Integer.toHexString((0x000000ff & b) | 0xffffff00).substring(6),
                String.format("%02x", b, args));
            System.out.println ("Done");
        }
    }
    

    您会看到这两个表达式是相同的 - 它只是吐出Done,因为这两个表达式在所有情况下都会产生相同的结果。

    【讨论】:

    • 看来你可以删除` | 0xffffff00).substring(6)` 位,功能没有任何变化。
    • 不完全是,@Cameron,它会为 0..15 范围提供一个 1 字符的字符串 - 问题中的代码总是给你两个字符。
    • 啊,是的,toHexString 没有填充。 Formatter.format 可能是更好的方法。
    猜你喜欢
    • 1970-01-01
    • 2012-04-09
    • 2023-02-08
    • 1970-01-01
    • 2018-04-26
    • 2021-04-07
    • 2023-04-02
    • 1970-01-01
    • 2011-03-19
    相关资源
    最近更新 更多