【问题标题】:bitwise-ANDing with 0xff is important?与 0xff 进行位与运算很重要吗?
【发布时间】:2013-10-04 09:18:02
【问题描述】:

在此代码中,与 0xff 进行按位与运算本质上是否意味着返回相同的值?

byte[] packet = reader.readPacket();
short sh;
sh = packet[1];
sh &= 0xFF;
System.out.print(sh+" ");

奇怪的是,如果不包含 ANDing,我会得到 -1,但包含时会得到 255 有人可以解释原因吗?

在我看来,0xff 只是 1111 1111。不是吗?

【问题讨论】:

    标签: java byte bitwise-operators short bitwise-and


    【解决方案1】:

    是的,0xff 就是 1111 1111。但这是试图显示无符号字节值,即使在 Java 中 bytes 已签名。对于签名的byte,值0xff-1,但在short 中是255

    当读取0xffbyte 值时,打印该值将产生-1。因此,它被分配给short,它具有更大的范围,并且可以将通常溢出为负数的byte 值存储为byte 作为正整数,例如144 作为byte0x90 或-112,但它可以正确存储为144 作为short

    因此-1byte 值被分配给short。但这有什么作用?发生原始扩展转换,并且负值被符号扩展。所以1111 1111 变成了11111111 11111111,仍然是-1,但这次是short

    然后使用位掩码0xff (00000000 11111111) 再次取出最后8位:

      -1: 11111111 1111111
    0xFF: 00000000 1111111
    ======================
     255: 00000000 1111111
    

    这只是一种获取无符号byte 值的方法,将其转换为short,然后从byte 中屏蔽掉原始位,将其显示为无符号值。

    【讨论】:

    • 我会给你一个赞成票,但你必须等待 24 分钟才能得到我的赞成票。我目前没有选票。
    • “所以 -1 的字节值被分配给了一个 short。但这有什么作用呢?发生了原始的加宽转换,负值被符号扩展。” - 优秀的信息。 “然后位掩码 0xff (00000000 11111111) 用于再次取出最后 8 位”——呵呵.. 就是这样.. 非常感谢伙计...
    【解决方案2】:

    byte 的范围是 -128 到 127。这意味着某些值是负数。这是设置了最高位的所有值。所以(byte) 0xFF 是-1。当您使用符号扩展使其成为有符号短时,它变为 (short) 0xFFFF,即 -1 作为短。当你屏蔽它时,它会切断扩展位,并且你将字节视为无符号。


    除非您的代码与您在问题中的代码不同,否则您不会得到 -1。

    for (byte b = Byte.MIN_VALUE; b < Byte.MAX_VALUE; b++) {
        short s = b;
        s &= 0xff;
        System.out.println(b + " & 0xFF = " + s);
    }
    

    打印

    -128 & 0xFF = 128
    -127 & 0xFF = 129
    ....
    -2 & 0xFF = 254
    -1 & 0xFF = 255
    0 & 0xFF = 0
    1 & 0xFF = 1
    ...
    125 & 0xFF = 125
    126 & 0xFF = 126
    

    【讨论】:

    • 在问题中他确实说“奇怪的是,如果包含 ANDing,我会得到 -1”。在我看来,他似乎知道发生了什么,但想知道为什么。
    • @SimonAndréForsberg 好点。这是我所期望的一点也不奇怪。
    • @SimonAndréForsberg 感谢您的支持……你说得对……我想知道为什么……
    【解决方案3】:

    (假设到处都是补码)两件事:

    1. 字节是有符号的,所以一个字节中的0xff等于-1。
    2. 当从较小的数据类型转换为较大的数据类型时(在本例中,从byte 转换为short), 被保留。所以,sh = packet[1] 会将sh 设置为-1,即0xffff

    第 2 点的问题是,只要原始值为负数,“额外”位就会用 1 填充以保持该值。与 0xff 进行 AND 运算的想法是 sh 现在包含 0x00ff,而那些“额外”的 1 现在已被删除。

    【讨论】:

    • “价值被保留。”..这解释了..非常感谢!
    猜你喜欢
    • 2021-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-04
    • 1970-01-01
    相关资源
    最近更新 更多