我有一个字节变量:
byte varB = (byte) -1; // binary view: 1111 1111
我希望看到两个最左边的位并执行6位数的 无符号右移 :
varB = (byte) (varB >>> 6);
但我正在 -1 ,就像它是int类型一样,并且 3 只有我换了30!
我如何解决这个问题并且只能通过6位移位获得结果?
答案 0 :(得分:8)
原因是与位移时发生的int
数字提升相关联的符号扩展。在转移之前,值varB
会提升为int
。向右转的无符号位移确实会发生,但是在转换回byte
时它的效果会被丢弃,而varB (byte) : 11111111
promoted to int : 11111111 11111111 11111111 11111111
shift right 6 : 00000011 11111111 11111111 11111111
cast to byte : 11111111
只保留最后8位:
&
您可以使用按位和运算符0xFF
在移位之前屏蔽掉不需要的位。与varB = (byte) ((varB & 0xFF) >>> 6);
进行位操作仅保留8个最低有效位。
varB (byte) : 11111111
promoted to int : 11111111 11111111 11111111 11111111
bit-and mask : 00000000 00000000 00000000 11111111
shift right 6 : 00000000 00000000 00000000 00000011
cast to byte : 00000011
现在发生了什么:
{{1}}
答案 1 :(得分:4)
因为在
要点是小于 int 的类型会以静默方式扩展为int,移位然后缩小。
这使您的单行有效地相当于:
byte b = -1; // 1111_1111
int temp = b; // 1111_1111_1111_1111_1111_1111_1111_1111
temp >>>= 6; // 0000_0011_1111_1111_1111_1111_1111_1111
b = (byte) temp; // 1111_1111
使用无符号语义(仅需要手动缩小转换),仅移动您需要使用无符号语义进行扩展转换所需的字节:
byte b = -1; // 1111_1111
int temp = b & 0xFF; // 0000_0000_0000_0000_0000_0000_1111_1111
temp >>>= 6; // 0000_0000_0000_0000_0000_0000_0000_0011
b = (byte) temp; // 0000_0011