Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么Java对负字节的无符号位移位如此奇怪?_Java_Bit Shift_Primitive Types - Fatal编程技术网

为什么Java对负字节的无符号位移位如此奇怪?

为什么Java对负字节的无符号位移位如此奇怪?,java,bit-shift,primitive-types,Java,Bit Shift,Primitive Types,我有一个字节变量: byte varB = (byte) -1; // binary view: 1111 1111 我希望看到最左边的两个位,并执行6位的无符号右移: varB = (byte) (varB >>> 6); 但是我得到了-1,就好像它是int类型的一样,只有当我换30档时,我才能得到3 我如何解决这个问题,并仅通过6位移位获得结果?原因是位移位时,与数值提升到int相关的符号扩展。值varB在移位前提升为int。确实会发生无符号位向右移位,但当回退到字节时

我有一个字节变量:

byte varB = (byte) -1; // binary view: 1111 1111
我希望看到最左边的两个位,并执行6位的无符号右移

varB = (byte) (varB >>> 6);
但是我得到了-1,就好像它是int类型的一样,只有当我换30档时,我才能得到3


我如何解决这个问题,并仅通过6位移位获得结果?

原因是位移位时,与数值提升到
int
相关的符号扩展。值
varB
在移位前提升为
int
。确实会发生无符号位向右移位,但当回退到
字节时,其效果会下降,这只会保留最后8位:

varB (byte)     : 11111111
promoted to int : 11111111 11111111 11111111 11111111
shift right 6   : 00000011 11111111 11111111 11111111
cast to byte    : 11111111
您可以使用按位and运算符
&
在移位前屏蔽掉不需要的位。与
0xFF
进行位和运算只保留8个最低有效位

varB = (byte) ((varB & 0xFF) >>> 6);
下面是现在发生的事情:

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
因为这就是java中字节移位在语言中的定义:

其要点是,小于int的类型被悄悄地扩展到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
要仅移动字节,您需要使用无符号语义显式地进行加宽转换(并且也需要手动进行加宽转换):


char
byte
short
的所有算术运算首先升级到
int
。“升级到int时”表示将byte转换为int:
(int)varB
。虽然它们的值是相同的,但二进制文件变化很大。
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