java 如何从java中的字节读取有符号的int?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7157901/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how to read signed int from bytes in java?
提问by Siva
I have a spec which reads the next two bytes are signed int.
我有一个规范,它读取接下来的两个字节是有符号整数。
To read that in java i have the following
要在 java 中阅读,我有以下内容
When i read a signed int in java using the following code i get a value of 65449
当我使用以下代码在 java 中读取有符号整数时,我得到的值为 65449
Logic for calculation of unsigned
无符号计算逻辑
int a =(byte[1] & 0xff) <<8
int b =(byte[0] & 0xff) <<0
int c = a+b
I believe this is wrong because if i and with 0xff i get an unsigned equivalent
我相信这是错误的,因为如果我和 0xff 我得到一个无符号的等价物
so i removed the & 0xff and the logic as given below
所以我删除了 & 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
I tried to offset these values with the way the spec reads but this looks wrong.Since the size of the heap doesnt fall under this.
我试图用规范读取的方式来抵消这些值,但这看起来是错误的。因为堆的大小不属于这个范围。
Which is the right way to do for signed int calculation in java?
在java中进行有符号int计算的正确方法是什么?
Here is how the spec goes
这是规范的方式
somespec() { xtype 8 uint8 xStyle 16 int16 }
xStyle :A signed integer that represents an offset (in bytes) from the start of this Widget() structure to the start of an xStyle() structure that expresses inherited styles for defined by page widget as well as styles that apply specifically to this widget.
somespec() { xtype 8 uint8 xStyle 16 int16 }
xStyle :一个有符号整数,表示从该 Widget() 结构的开头到 xStyle() 结构的开头的偏移量(以字节为单位),该结构表示由页面小部件定义的继承样式以及专门应用于该小部件的样式.
回答by Peter Lawrey
If you value is a signed 16-bit you want a short
and int is 32-bit which can also hold the same values but not so naturally.
如果您的 value 是有符号的 16 位,您需要 ashort
并且 int 是 32 位,它也可以保存相同的值,但不是那么自然。
It appears you wants a signed little endian 16-bit value.
看来您想要一个带符号的小端 16 位值。
byte[] bytes =
short s = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getShort();
or
或者
short s = (short) ((bytes[0] & 0xff) | (bytes[1] << 8));
BTW: You can use an int but its not so simple.
顺便说一句:您可以使用 int 但它不是那么简单。
// to get a sign extension.
int i = ((bytes[0] & 0xff) | (bytes[1] << 8)) << 16 >> 16;
or
或者
int i = (bytes[0] & 0xff) | (short) (bytes[1] << 8));
回答by Stephen C
Assuming that bytes[1] is the MSB, and bytes[0] is the LSB, and that you want the answer to be a 16 bit signed integer:
假设 bytes[1] 是 MSB,bytes[0] 是 LSB,并且您希望答案是 16 位有符号整数:
short res16 = ((bytes[1] << 8) | bytes[0]);
Then to get a 32 bit signed integer:
然后得到一个 32 位有符号整数:
int res32 = res16; // sign extends.
By the way, the specification should say which of the two bytes is the MSB, and which is the LSB. If it doesn't and if there aren't any examples, you can't implement it!
顺便说一下,规范应该说明两个字节中的哪个是 MSB,哪个是 LSB。如果没有,如果没有任何例子,你就无法实现它!
Somewhere in the spec it will say how an "int16" is represented. Paste THAT part. Or paste a link to the spec so that we can read it ourselves.
规范中的某个地方会说明“int16”是如何表示的。粘贴那个部分。或者粘贴一个链接到规范,以便我们可以自己阅读。
回答by SJuan76
I can't compile it right now, but I would do (assuming byte1
and byte0
are realling of byte type).
我现在无法编译它,但我会这样做(假设byte1
并且byte0
正在实现字节类型)。
int result = byte1;
result = result << 8;
result = result | byte0; //(binary OR)
if (result & 0x8000 == 0x8000) { //sign extension
result = result | 0xFFFF0000;
}
if byte1
and byte0
are ints, you will need to make the `&0xFF
如果byte1
和byte0
是整数,您将需要制作`&0xFF
UPDATE because Java forces the expression of an if to be a boolean
更新,因为 Java 强制 if 的表达式为布尔值
回答by AlexR
Take a look on DataInputStream.readInt()
. You can either steel code from there or just use DataInputStream: wrap your input stream with it and then read typed data easily.
看一看DataInputStream.readInt()
。您可以从那里使用钢代码,也可以仅使用 DataInputStream:用它包装您的输入流,然后轻松读取键入的数据。
For your convenience this is the code:
为了您的方便,这是代码:
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));
}
回答by Michael Litvin
do you have a way of finding a correct output for a given input? technically, an int size is 4 bytes, so with just 2 bytes you can't reach the sign bit.
你有办法为给定的输入找到正确的输出吗?从技术上讲,一个 int 大小是 4 个字节,所以只有 2 个字节你无法到达符号位。
回答by Gilbert Le Blanc
I ran across this same problem reading a MIDI file. A MIDI file has signed 16 bit as well as signed 32 bit integers. In a MIDI file, the most significant bytes come first (big-endian).
我在读取 MIDI 文件时遇到了同样的问题。MIDI 文件具有带符号的 16 位和带符号的 32 位整数。在 MIDI 文件中,最重要的字节在前(big-endian)。
Here's what I did. It might be crude, but it maintains the sign. If the least significant bytes come first (little-endian), reverse the order of the indexes.
这就是我所做的。它可能很粗糙,但它保持了这个标志。如果最低有效字节在前(little-endian),则反转索引的顺序。
pos is the position in the byte array where the number starts.
pos 是字节数组中数字开始的位置。
length is the length of the integer, either 2 or 4. Yes, a 2 byte integer is a short, but we all work with ints.
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;
}