11

我在一个项目中有几行代码,我看不到......

buffer[i] = (currentByte & 0x7F) | (currentByte & 0x80);

它从文件中读取文件缓冲区,存储为字节,然后如图所示传输到缓冲区 [i],但我不明白总体目的是什么,有什么想法吗?

谢谢

4

7 回答 7

9

正如其他答案已经说明的那样,(currentByte & 0x7F) | (currentByte & 0x80)相当于(currentByte & 0xFF)。JLS3 15.22.1说这被提升为int

当运算符 &、^ 或 | 的两个操作数 是可转换(第 5.1.8 节)为原始整数类型的类型,首先对操作数执行二进制数字提升(第 5.6.2 节)。按位运算符表达式的类型是操作数的提升类型。

因为 JLS3 5.6.2说当currentByte有类型byte并且0x7F是一个int(情况就是这样)时,两个操作数都被提升为int.

因此,buffer将是一个元素类型int或更宽的数组。

现在,通过在& 0xFF上执行int,我们有效地将原始范围 -128..127 映射到无符号范围 0..255,例如流byte经常使用的操作。java.io

您可以在以下代码片段中看到这一点。请注意,要了解这里发生的情况,您必须知道 Java 将整数类型(除了char)存储为2 的补码值。

byte b = -123;
int r = b;
System.out.println(r + "= " + Integer.toBinaryString(r));
int r2 = b & 0xFF;
System.out.println(r2 + "= " + Integer.toBinaryString(r2));

最后,对于一个真实世界的示例,请查看 Javadoc 和read方法的实现java.io.ByteArrayInputStream

/**
 * Reads the next byte of data from this input stream. The value 
 * byte is returned as an <code>int</code> in the range 
 * <code>0</code> to <code>255</code>. If no byte is available 
 * because the end of the stream has been reached, the value 
 * <code>-1</code> is returned. 
 */
public synchronized int read() {
return (pos < count) ? (buf[pos++] & 0xff) : -1;
}
于 2009-02-18T14:10:33.397 回答
4
 (currentByte & 0x7F) | (currentByte & 0x80)

相当于

 currentByte & (0x7F | 0x80)

这等于

 currentByte & 0xFF

这与

 currentByte

编辑:我只看了右边的作业,我仍然认为等价是真的。

但是,似乎代码想要将带符号的字节转换为更大的类型,同时将字节解释为无符号的。

有没有更简单的方法将有符号字节转换为 Java 中的无符号字节?

于 2009-02-18T13:03:54.197 回答
3

我想有人在这里想太多了。那是不对的。

我只有一句话

  • 原作者担心运行时将字节替换为本机有符号整数(可能是 32 位),并明确试图告诉我们有关符号位“特殊”的一些信息?

这是留下的代码。除非你知道你在一个可疑的运行时间?无论如何,“缓冲区”的类型是什么?

于 2009-02-18T13:02:32.547 回答
2

复杂的按位逻辑完全是多余的。

for (int i = 0; i < buffer.length; i++) {
    buffer[i] = filebuffer[currentPosition + i] & 0xff;
}

做同样的事情。如果缓冲区被声明为一个字节数组,你甚至可以省略 & 0xff,但不幸的是声明没有显示。

原因可能是最初的开发人员对用 Java 签名的字节感到困惑。

于 2009-02-18T13:03:36.317 回答
2

按位与运算的结果在两个位都为 1 的位上为 1,而按位或运算的结果在任何一个 bot 位为 1 的位上具有一个。

因此,对值 0x65 的示例评估:

  01100101 0x65
& 01111111 0x7F
===============
  01100101 0x65

  01100101 0x65
& 10000000 0x80
===============
  00000000 0x00

  01100101 0x65
| 00000000 0x00
===============
  01100101 0x65
于 2009-02-18T13:08:40.550 回答
0

这些逻辑运算的好处是:您可以尝试所有可能的组合(全部 256 种)并验证您是否得到了预期的答案。

于 2009-02-18T20:09:17.560 回答
0

Turns out, the file which the byte was being read from was in a signed bit notation, and of a different length, therefore it was requried to perform this task to allow it to be extended to the java int type, while retaining its correct sign :)

于 2009-02-20T10:38:12.270 回答