如何在Java中将有符号的16位整数转换为无符号的16位整数? [英] How to convert signed 16 bit integer to unsigned 16 bit integer in Java?

查看:405
本文介绍了如何在Java中将有符号的16位整数转换为无符号的16位整数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有下面的布局,我需要在其中表示数据,然后最后我需要从中制作一个字节数组。我需要从Java代码中以以下格式表示数据,然后将字节数组发送到C ++程序,C ++程序依次将c ++程序解压缩字节数组并从中提取相关内容-

I have my below layout in which I need to represent my data and then finally I need to make one byte array out of that. I need to represent my data in the below format from Java code and then send the byte array to my C++ program which in turns c++ program unpacks the byte array and extract the relevant stuff from it -

// 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 计算是错误的,因为我使用的是 Short 表示 dataSize ,其最大值可以为 32767 ,但 dataSize 规范为 uint16_t ,如上所示,它是无符号16位整数,最大值可以大于 32767

So I started like this in Java which works fine on a simple use case which makes a single byte array out of this but I am thinking my dataSize calculation is wrong since I am using Short for the dataSize which can take maximum value as 32767 but dataSize specification is uint16_t as shown above which is unsigned 16-bit integer which can take maximum value more than 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

Let's say if the length of data is 37714 (data.length), then dataSize will come as negative -27822.

所以我的问题是-有什么办法可以在Java中使用无符号的16位整数(可以在上面的代码中使用)还是以某种方式进行转换?

So my question is - Is there any way I can have unsigned 16 bit Integer in java which I can use in my above code or some way to cast it?

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

Does my above code looks right with the above specifications or is there anything wrong which might cause problem if we have some big strings coming up.

推荐答案

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

Java's only unsigned type is char, and it happens to be 16-bit wide. However, this is not the right choice to represent length: you should use int internally, and convert to/from 16-bit short only during serialization and deserialization.

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

short tmp = getShort(...);
int dataSize = ((int)tmp) & 0xFFFF;

0xFFFF 是一个16位的掩码 会删除 int 不需要的部分。请注意,如果 tmp 在反序列化期间恰好为负值,则屏蔽将使其再次变为正数,从而产生已发送给您的值。

0xFFFF is a 16-bit "mask" that cuts off the undesired bits of an int. Note that if tmp happens to be negative during deserialization, masking will make it positive again, producing the value that has been sent to you.

这篇关于如何在Java中将有符号的16位整数转换为无符号的16位整数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆