java - 有没有办法在 Java 中将 0x80-0xFF 范围表示为单个字节?

标签 java arrays

我已经为此苦苦挣扎了一段时间,我正在尝试计算一个 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/

相关文章:

java - 找出文件中与字符串数组中的任何单词都不匹配的单词数

arrays - 如何将 (StorableArray (Int, Int) Word8) 转换为惰性 ByteString?

arrays - 在 bash 脚本中访问关联数组

java - 第一个程序导致大量错误

Java KeyEvent - 键代码与扩展键代码

java - 拍照后显示 fragment

arrays - C语言中查找数组中最大元素的函数

java - Spark在java中提交(SparkLauncher)

java - 学习EJB及优势

c++ - 运算符重载 [][] 二维数组 C++