在Java中对"签名"数据执行按位左移 - 更好地转移到JNI?

gjt*_*ian 5 c# java java-native-interface byte bit-manipulation

在过去的一周里,我一直在询问有关十六进制和按位操作(此处和其他地方)的问题,试图将我的头围绕在Java中.经过大量的谷歌搜索和懊恼之后,我必须最后一次询问如何对应该是无符号的位执行逻辑运算,但在Java中表示为signed.

好的:我正在将一个C#程序移植到Java.该程序处理位图操作,因此应用程序中的大部分数据表示为byte无符号的8位整数.有许多建议改为short在Java中使用数据类型,以便"模仿"尽可能接近无符号的8字节整数.

我不相信这对我来说是可能的,因为C#代码用我的字节数据执行各种移位和AND操作.例如,if data是一个字节数组,并且这个代码块存在于C#中:

int cmdtype = data[pos] >> 5;
int len = (data[pos] & 0x1F) + 1;

if (cmdtype == 7)
{
    cmdtype = (data[pos] & 0x1C) >> 2;
    len = ((data[pos] & 3) << 8) + data[pos + 1] + 1;
    pos++;
}
Run Code Online (Sandbox Code Playgroud)

这不是一个简单的问题,只需将其data作为一个short并完成它以使其在Java中工作.就逻辑而言,我的数据保持8位无符号的要求是显着的; 16位无符号将像上面那样拧动数学.我在这儿吗?事实上,在此之前"假铸造"之后byte0XFFcharJava和没有得到正确的结果,恐怕我进入了死胡同.

现在,在代码的另一部分,我正在执行一些位图像素操作.由于这是一个漫长的过程,我决定通过JNI调用本机代码.我最近意识到,在那里我可以使用uint8_t数据类型并获得最接近C#byte数据类型的表示.

解决方案是否使我的所有数据相关功能都在JNI中运行?这似乎非常低效,无论是重写还是表演.解决方案是用Java重做数学所以逻辑保持不变吗?这似乎是正确的,但有可能诱发动脉瘤,更不用说错误的数学.

我感谢任何和所有的建议.

jdm*_*hal 3

请注意:您不能直接转换为short,因为负数将在逻辑上扩展。

也就是说,1111 1101直接转换为字节 (-5)short将得到1111 1111 1111 1101(-5),而不是0000 0000 1111 1101(253)。转换时,必须使用 AND 运算删除前导:

short shortValue = ((short)(byteValue)) & 0xFF;
Run Code Online (Sandbox Code Playgroud)

我知道像这样复杂的位操作是可能的,因为我已经在使用 Java Swing 应用程序处理遗留二进制消息传递协议时完成了同样的事情。我强烈建议您以某种方式将其抽象化,这样您只需处理它一次。这是否意味着将您的“字节”包装在一个类中以将它们存储为短整型并处理转换操作,或者定义一个静态实用程序在一次传递中执行转换和位操作,以便您始终存储字节。