繁体   English   中英

如何从java中的字节读取有符号的int?

[英]how to read signed int from bytes in java?

我有一个规范,它读取接下来的两个字节是有符号整数。

要在java中阅读,我有以下内容

当我使用以下代码在 java 中读取有符号整数时,我得到的值为 65449

无符号计算逻辑

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

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

int c = a+b 

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

所以我删除了 & 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中进行有符号int计算的正确方法是什么?

这是规范的方式

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

如果您的值是有符号的 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));

顺便说一句:您可以使用 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));

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

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

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

int res32 = res16;  // sign extends.

顺便说一下,规范应该说明两个字节中的哪个是 MSB,哪个是 LSB。 如果没有,如果没有任何例子,你就无法实现它!


规范中的某个地方会说明“int16”是如何表示的。 粘贴那个部分。 或者粘贴一个链接到规范,以便我们可以自己阅读。

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

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

如果byte1byte0是整数,则需要将 `&0xFF

更新,因为 Java 强制 if 的表达式为布尔值

看看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));
}

你有办法为给定的输入找到正确的输出吗? 从技术上讲,int 大小为 4 个字节,因此只有 2 个字节您无法到达符号位。

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

这就是我所做的。 它可能很粗糙,但它保持了标志。 如果最低有效字节在前(小端),则反转索引的顺序。

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

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

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;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM