我已经为此苦苦挣扎了一段时间,我正在尝试计算一个 byte[] 的校验和作为数组中 16 位字的 1s 补码总和的 1s 补码。总和相当简单(尽管我确信我可以更有效率)但是当我翻转位并得到一个“负”值时,它的符号扩展到 4 个字节。按位执行并使用 0xff 给出了正确的值,但是因为我试图将校验和包含在另一个字节数组中,所以我需要它作为一个字节。转换回一个字节再次给我 4 字节 int。奇怪的是,我可以将这个(4 字节)值存储在一个字节数组中并打印它而不会引起问题。有没有办法强制 Java 只给我一个带负号位的字节?在此特定示例中,字节为 0xef 和 0xfd。
我计算校验和的代码是:
public byte[] checksum (byte[] b) {
byte[] check = new byte[3] ;
check[1] += b[0];
check[2] += b[1];
check[1] += b[2];
check[2] += b[3];
check[1] += b[4];
check[2] += b[5];
check[1] += b[6];
check[2] += b[7];
check[1] += b[8];
check[2] += b[9];
check[1] += b[10];
check[2] += b[11];
check[1] += b[12];
check[2] += b[13];
check[1] += b[14];
check[2] += b[15];
check[1] += b[16];
check[2] += b[17];
check[1] += b[18];
check[2] += b[19];
check[2] += check[0] ;
byte[] ret = new byte[2] ;
ret[0] = (byte)~check[1];
ret[1] = (byte)~check[2];
return ret ;
}
再次明确,这给了我一个大小为 2 的 byte[],其中每个元素似乎是 4 个字节。
打印返回的数组
byte[] r = checksum (b);
for (int i = 0; i < r.length; ++ i) {
System.out.println (String.format("0x%2s", Integer.toHexString(r[i])).replace(' ', '0')) ;
}
显示
0xffffffef
0xfffffffd
这怎么可能,我该如何避免呢?如果它只是一个显示问题那很好,但看起来我返回的数组的每个元素实际上是 4 个字节。
最佳答案
问题不在于您的字节数组,而在于您如何打印它。 Integer.toHexString()
需要一个 int
。当您将 byte
作为 int
传递时,将执行自动扩大转换,其中包括符号扩展。您可以像这样撤消符号扩展的影响:
Integer.toHexString(r[i] & 0xFF)
关于java - 有没有办法在 Java 中将 0x80-0xFF 范围表示为单个字节?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43595905/