带符号字节的按位AND运算

时间:2015-05-11 21:30:16

标签: java bit-manipulation

以下是代码:

int i = 200;
byte b = (byte) 200;
System.out.println(b);
System.out.println((short) (b));
System.out.println((b & 0xff));
System.out.println((short) (b & 0xff));

这是输出:

-56
-56
200
200

按位AND和0xff不应该改变b中的任何内容,但显然它确实有效,为什么?

3 个答案:

答案 0 :(得分:8)

它有效,因为200超出了最大可能(签名)byte127。由于此溢出,该值已分配-56。值得-128的最重要字节已设置。

11001000

前两个输出语句因此显示-56,并且转换为short将执行符号扩展以保留负值。

执行& 0xff时,会发生两件事。首先,该值会提升为int,并带有符号扩展名。

11111111 11111111 11111111 11001000

然后,执行bit-and,仅保留最后8位。此处,第8位不再是-128,而是128,因此会恢复200

00000000 00000000 00000000 11001000

无论值是否转换为short,都会发生这种情况; short有16位,可以轻松代表200

00000000 11001000

答案 1 :(得分:1)

Java byte是签名类型。这就是您在打印时看到负数的原因:200或0xC8高于byte可表示的最大正数,因此它被解释为负数byte。< / p>

但是,0xff常量是int。在byteint * 上执行算术和按位逻辑运算时,结果变为int。这就是为什么您在第二组示例中看到200打印的原因:(b & 0xff)生成一个整数200,在转换为200之后仍为short,因为200符合short而不会变为负面。

* 或其他byte,就此而言; Java标准指定了根据操作数类型应用的转换列表。

答案 2 :(得分:0)

使用不同的整数类型是一个雷区。

例如,这里发生了什么?

byte b = (byte) 200;

它实际上相当于

int i = 200;
byte b = (byte)i;

并且缩小广播(byte)只取int值的最低8位。