我花了一天的大部分时间来寻找一个二进制重构错误,想知道为什么:
特定的代码行看起来像这样(dataBuffer
是一个字节数组):
short data = (short) ((short)dataBuffer[curPos + 3] << 8 | ((short)dataBuffer[curPos + 2]));
偶尔会返回垃圾,直到我给低阶单词添加掩码:
short data = (short) ((short)dataBuffer[curPos + 3] << 8 | (((short)dataBuffer[curPos + 2])) & 0xff);
所以,我的解释是,从byte
到short
的类型强制转换偶尔会在高阶单词中留下垃圾,导致在or-ed时出现问题…但这并没有多大意义。
这段代码取自c++,在那里工作得很好…我错过了什么?
这是符号扩展。Java中的所有byte
值都是有符号的,因此任何大于127的字节值实际上都是一个负数。因此,当字节值为byte
时,例如0x90(= 144十进制)实际上被视为-112。当它扩大到short
时,它变成0xff90(仍然是-112)。您需要用0xff掩码值来恢复0x0090
所需的位模式。
short data = (short) ((dataBuffer[curPos + 3] << 8) | (dataBuffer[curPos + 2] & 0xff));
实际上,这些强制转换是毫无用处的。位操作符的操作数在应用操作符之前总是被提升为int
值1。
1或long
,如果其中任何一个是long