如何从java中的字节读取signed int?

时间:2011-08-23 08:00:40

标签: java binary

我有一个规范,读取接下来的两个字节是signed int。

要在java中读取我有以下内容

当我使用以下代码在java中读取signed int时,我得到的值为65449

计算无符号的逻辑

int a =(byte[1] & 0xff) <<8

int b =(byte[0] & 0xff) <<0

int c = a+b 

我认为这是错误的,因为如果我和0xff我得到一个无符号的等价物

所以我删除了&amp; 0xff和下面给出的逻辑

int a = byte[1] <<8
int b = byte[0] << 0
int c = a+b
which gives me the value -343
byte[1] =-1
byte[0]=-87

我试图用规范读取的方式来抵消这些值,但这看起来很错误。因为堆的大小不属于此范围。

在java中进行signed int计算的正确方法是什么?

规范如何发布

somespec() { xtype 8 uint8 xStyle 16 int16 }  xStyle:一个有符号整数,表示从此Widget()结构的开头到xStyle()结构的开头的偏移量(以字节为单位),该结构表示由页面窗口小部件定义的继承样式以及专门应用于此窗口小部件的样式

6 个答案:

答案 0 :(得分:14)

如果你的值是有符号的16位,你想要一个short而int是32位,它也可以保持相同的值,但不是那么自然。

看来你想要一个带符号的小端16位值。

byte[] bytes = 
short s = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getShort();

short s = (short) ((bytes[0] & 0xff) | (bytes[1] << 8));

BTW:你可以使用int但不是那么简单。

// to get a sign extension.
int i = ((bytes[0] & 0xff) | (bytes[1] << 8)) << 16 >> 16;

int i = (bytes[0] & 0xff) | (short) (bytes[1] << 8));

答案 1 :(得分:4)

假设bytes [1]是MSB,而bytes [0]是LSB,并且您希望答案是16位有符号整数:

short res16 = ((bytes[1] << 8) | bytes[0]);

然后得到一个32位有符号整数:

int res32 = res16;  // sign extends.

顺便说一句,规范应该说两个字节中的哪一个是MSB,哪个是LSB。如果没有,如果没有任何示例,则无法实现!


在规范的某处,它将说明如何表示“int16”。粘贴那部分。或者粘贴指向规范的链接,以便我们自己阅读。

答案 2 :(得分:2)

我现在无法编译它,但我会这样做(假设byte1byte0正在重新编写字节类型)。

 int result = byte1;
 result = result << 8;
 result = result | byte0;  //(binary OR)
 if (result & 0x8000 == 0x8000) { //sign extension
   result = result | 0xFFFF0000;
 }

如果byte1byte0是整数,则需要制作`&amp; 0xFF

UPDATE因为Java强制if表达式为布尔值

答案 3 :(得分:2)

看看DataInputStream.readInt()。您可以从那里加工代码或只使用DataInputStream:用它包装输入流,然后轻松读取类型化数据。

为方便起见,这是代码:

public final int readInt() throws IOException {
    int ch1 = in.read();
    int ch2 = in.read();
    int ch3 = in.read();
    int ch4 = in.read();
    if ((ch1 | ch2 | ch3 | ch4) < 0)
        throw new EOFException();
    return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
}

答案 4 :(得分:1)

您是否有办法为给定输入找到正确的输出? 从技术上讲,int size是4个字节,所以只有2个字节就无法到达符号位。

答案 5 :(得分:0)

我在读取MIDI文件时遇到了同样的问题。 MIDI文件具有16位和32位带符号整数。在MIDI文件中,最高有效字节在前(大端)。

这就是我所做的。它可能很粗糙,但仍保持了这种迹象。如果最低有效字节排在第一位(小尾数),请反转索引的顺序。

pos是字节数组中数字开头的位置。

length是2或4的整数的长度。是的,一个2字节的整数是一个短整数,但是我们都使用int。

private int convertBytes(byte[] number, int pos, int length) {
    int output = 0;
    if (length == 2) {
        output = ((int) number[pos]) << 24;
        output |= convertByte(number[pos + 1]) << 16;
        output >>= 16;
    } else if (length == 4) {
        output = ((int) number[pos]) << 24;
        output |= convertByte(number[pos + 1]) << 16;
        output |= convertByte(number[pos + 2]) << 8;
        output |= convertByte(number[pos + 3]);
    }
    return output;
}

private int convertByte(byte number) {
    return (int) number & 0xff;
}