将字节转换为整数时出现的问题(特定于Java?)

将字节转换为整数时出现的问题(特定于Java?),java,binary,Java,Binary,关于从字节到整数的转换,我有点困惑。考虑下面的代码: byte[] data = new byte[] { 0, (byte) 0xF0 }; int masked = data[0] << 8 & 0xFF | data[1] & 0xFF; //240 int notMasked = data[0] << 8 | data[1]; //-16 byte[]data=新字节[]{0,(byte)0xF0}; int masked=data[0]Jav

关于从字节到整数的转换,我有点困惑。考虑下面的代码:

byte[] data = new byte[] { 0, (byte) 0xF0 };

int masked = data[0] << 8 & 0xFF | data[1] & 0xFF; //240
int notMasked = data[0] << 8 | data[1]; //-16
byte[]data=新字节[]{0,(byte)0xF0};
int masked=data[0]Java字节是有符号的(很不幸)-因此,当您将值提升为
int
以执行按位
|
时,它最终被符号扩展为
0xFFFFFFF0
。然后将
|
数据[0]
弄乱。使用
&0xff
的屏蔽将其转换为240的整数值(仅
0x000000F0

然而,你遇到了一个问题。此代码:

int masked = data[0] << 8 & 0xFF | data[1] & 0xFF;
int-masked=data[0]Java字节是有符号的(很不幸)-因此,当您将值提升为
int
以执行按位
|
时,它最终被符号扩展为
0xFFFFFFF0
。然后将
|
数据[0]
弄乱。使用
&0xff
的屏蔽将其转换为240的整数值(仅
0x000000F0

然而,你遇到了一个问题。此代码:

int masked = data[0] << 8 & 0xFF | data[1] & 0xFF;
int masked=data[0]它类似于已知的“谜题”

产生

-1
不换班?这是因为在编译算术/移位/比较表达式之前,javac将byte(以及short和char)提升为int或long(如果表达式中有long),因此它的工作方式如下

x -> int = 0xFFFFFFFF; 0xFFFFFFF >>> 1 = 0x7FFFFFF; (byte)0x7FFFFFF -> 0xFF
它类似于一个已知的“谜题”

产生

-1
不换班?这是因为在编译算术/移位/比较表达式之前,javac将byte(以及short和char)提升为int或long(如果表达式中有long),因此它的工作方式如下

x -> int = 0xFFFFFFFF; 0xFFFFFFF >>> 1 = 0x7FFFFFF; (byte)0x7FFFFFF -> 0xFF

啊哈!所以
|
&
都提升为整数,所以
&0xFF
发生在整数值上。这充分说明了这一点,非常感谢@Miquel:
&0xFF
会升级到
int
,所以
|
不必升级,如果你明白我的意思的话:)跟进:这当然是特定于Java的,但是其他语言也会这样做吗?是的。很好,抓住你了。谢谢@米克尔:我不知道所有的语言。例如,在C语言中,
byte
是无符号的,因此问题不会出现。看我的编辑虽然-你的代码仍然有问题,我想。啊哈!所以
|
&
都提升为整数,所以
&0xFF
发生在整数值上。这充分说明了这一点,非常感谢@Miquel:
&0xFF
会升级到
int
,所以
|
不必升级,如果你明白我的意思的话:)跟进:这当然是特定于Java的,但是其他语言也会这样做吗?是的。很好,抓住你了。谢谢@米克尔:我不知道所有的语言。例如,在C语言中,
byte
是无符号的,因此问题不会出现。但请看我的编辑-我认为您的代码仍然有一个问题。我不久前做了一些代码的C到Java端口,它使用了大量的按位操作,并提出了一个简化代码的方法。没有关于这些的质量和效率的保证,但他们为我做了这项工作。不久前,我做了一些代码的C到Java端口,使用了大量的按位操作,并提出了一个解决方案,使事情变得更简单。对于这些函数的质量和效率没有保证,但它们为我完成了任务。很好:)但是没有人会感到困惑:您在这里使用的是带符号的移位运算符(
>>
),而不是普通的(
>>
)嗯,我认为>>>被称为unsigned,否则就没有什么问题了,是吗?很好:)但这样就不会让人困惑了:你在这里玩的是带符号的移位运算符(
>>
),而不是普通的(
>>
)嗯,我认为>>>被称为unsigned,否则就没有谜题了,是吗?