Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Java中将有符号16位整数转换为无符号16位整数?_Java_C++_Bytearray_Unsigned_Bytebuffer - Fatal编程技术网

如何在Java中将有符号16位整数转换为无符号16位整数?

如何在Java中将有符号16位整数转换为无符号16位整数?,java,c++,bytearray,unsigned,bytebuffer,Java,C++,Bytearray,Unsigned,Bytebuffer,我有下面的布局,我需要在其中表示我的数据,然后最后我需要用它制作一个字节数组。我需要用java代码把我的数据用下面的格式表示,然后把字节数组发送到C++程序,然后C++程序解压缩字节数组并从中提取相关的东西-< /p> // below is my data layout - // // key type - 1 byte // key len - 1 byte // key (variable size = key_len) // timestamp (sizeof uint64_t) //

我有下面的布局,我需要在其中表示我的数据,然后最后我需要用它制作一个字节数组。我需要用java代码把我的数据用下面的格式表示,然后把字节数组发送到C++程序,然后C++程序解压缩字节数组并从中提取相关的东西-< /p>
// below is my data layout -
//
// key type - 1 byte
// key len - 1 byte
// key (variable size = key_len)
// timestamp (sizeof uint64_t)
// data size (sizeof uint16_t), this is unsigned 16-bit integer.
// data (variable size = data size)
因此,我在Java中开始这样做,它在一个简单的用例中工作得很好,用它生成一个单字节数组,但我认为我的
dataSize
计算是错误的,因为我对
dataSize
使用
Short
,它的最大值为
32767
,但是
dataSize
规范是错误的
uint16\u t
如上所示,它是无符号16位整数,其最大值可能大于
32767

byte keyType = 101;
byte keyLength = 3;
byte[] key = {27, 55, 111};
long timestamp = System.currentTimeMillis();

byte[] data = "string data".getBytes("UTF-8");

// this is looking wrong to me since dataSize is uint16_t in my C++ specifications as shown above
short dataSize = (short) data.length;

int totalSize = (1 + 1 + keyLength + 8 + 2 + dataSize);
ByteBuffer bytes = ByteBuffer.allocate(totalSize);

bytes.put(keyType);
bytes.put(keyLength);
bytes.put(key);
bytes.putLong(timestamp);

// so this is also wrong
// what is the right way to send the dataSize?
bytes.putShort(dataSize);
bytes.put(data);

// write everthing as a single byte array:
byte[] byteArray = bytes.array();
假设数据的长度为
37714
(data.length),那么
dataSize
将为负值
-27822

所以我的问题是-有没有办法在java中使用无符号16位整数,我可以在上面的代码中使用它,或者用某种方法来转换它


我上面的代码是否符合上述规范,或者如果出现一些大字符串,是否存在任何可能导致问题的错误。

Java唯一的无符号类型是
char
,它恰好是16位宽。但是,这并不是表示长度的正确选择:您应该在内部使用
int
,并且仅在序列化和反序列化期间转换为16位short

int dataSize = data.length;
...
bytes.putShort((short)(dataSize & 0xFFFF));


0xFFFF
是一个16位的“掩码”,用于切断
int
中不需要的位。请注意,如果反序列化过程中
tmp
恰好为负值,屏蔽将使其再次为正值,从而生成发送给您的值。

Java中唯一的无符号16位整数是
char
,但您可以通过简单的强制转换将
short
转换为
char
。但是您最好使用
int
。为什么dataSize首先需要是有符号的short?只需声明它为int,并检查它是否小于65536,然后再调用putShort()。@LeeDanielCrocker您能提供一个示例吗?或者你的意思是说dasblinkenlight在下面建议了什么?他的版本有点风险,因为如果data.length>65536(并且你没有告诉我们这是从哪里来的,所以我们不知道),他的代码会默默地忽略这个错误,可能会截断数据。我建议明确检查该案例,并在需要时处理错误。谢谢您的建议。在我们的例子中,C++程序正在读取<代码> DATABASE 作为<代码> UTI1616T 。基本上我们需要从java程序中写入数据,并从C++中读取它。因此C++程序正在阅读<代码>数据化< /代码>作为<代码> UTI1616T 。如果我这样做
int size=37714;System.out.println((短)(大小和0xFFFF))
它打印出负数,这就是它存储在
字节中的内容。putShort
对吗?但是C++会正确地解码吗?到目前为止,我们所使用的C++应用程序不能正确地解码它。它在C++程序中是这样读的:<代码> Val= NtoHS(*RealTytReCube(缓冲));代码> @戴维C++应重新解释负数为由相同的16位组成的大正数。您的代码是否正确解释了一些数字
ntohs
可能会对字节进行重新排序,因此Java可能也需要进行一些重新排序。
short tmp = getShort(...);
int dataSize = ((int)tmp) & 0xFFFF;