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

时间:2017-04-24 19:05:52

标签: java arrays

我一直在与此争斗一段时间,我正在尝试计算字节[]的校验和作为数组中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个字节。

1 个答案:

答案 0 :(得分:6)

问题不在你的字节数组中,而在于你如何打印它。 Integer.toHexString()需要int。当您将byte作为int传递时,会执行自动扩展转换,其中包括符号扩展。您可以撤消符号扩展的效果,如下所示:

Integer.toHexString(r[i] & 0xFF)