简体   繁体   English

解决所有Java字节都已签名这一事实的最佳方法是什么?

[英]What is the best way to work around the fact that ALL Java bytes are signed?

In Java, there is no such thing as an unsigned byte. 在Java中,没有无符号字节。

Working with some low level code, occasionally you need to work with bytes that have unsigned values greater than 128, which causes Java to interpret them as a negative number due to the MSB being used for sign. 使用某些低级代码时,有时需要处理大于128的无符号值的字节,这会导致Java将其解释为负数,因为MSB用于符号。

What's a good way to work around this? 解决这个问题的好方法是什么? (Saying don't use Java is not an option) (说不要使用Java不是一个选项)

It is actually possible to get rid of the if statement and the addition if you do it like this. 如果你这样做,实际上可以摆脱if语句和添加。

byte[] foobar = ..;
int value = (foobar[10] & 0xff);

This way Java doesn't interpret the byte as a negative number and flip the sign bit on the integer also. 这样,Java不会将字节解释为负数,也会将整数上的符号位翻转。

When reading any single value from the array copy it into something like a short or an int and manually convert the negative number into the positive value it should be. 从数组中读取任何单个值时,将其复制为short或int之类的东西,并手动将负数转换为正值。

byte[] foobar = ..;
int value = foobar[10];
if (value < 0) value += 256 // Patch up the 'falsely' negative value

You can do a similar conversion when writing into the array. 写入数组时可以进行类似的转换。

使用int通常比使用short更好,因为java无论如何都在内部使用32位值(即使是字节,除非在数组中),因此使用int将避免不必要的转换为字节码中的短值。

Probably your best bet is to use an integer rather than a byte. 可能你最好的选择是使用整数而不是字节。 It has the room to allow for numbers greater than 128 without the overhead of having to create a special object to replace byte. 它有足够的空间来容纳大于128的数字,而无需创建一个特殊对象来替换字节。

This is also suggested by people smarter than me (everybody) 这也是比我聪明的人(每个人)所建议的

The best way to do bit manipulation/unsigned bytes is through using int s. 执行位操作/无符号字节的最佳方法是使用int Even though they are signed they have plenty of spare bits (32 total) to treat as an unsigned byte. 即使它们已经签名,它们也有足够的备用位(总共32位)作为无符号字节。 Also, all of the mathematical operators will convert smaller fixed precision numbers to int . 此外,所有数学运算符都会将较小的固定精度数转换为int Example: 例:

short a = 1s;
short b = 2s;
int c = a + b; // the result is up-converted
short small = (short)c; // must cast to get it back to short

Because of this it is best to just stick with integer and mask it to get the bits that you are interested in. Example: 因此,最好只使用整数并屏蔽它以获得您感兴趣的位。示例:

int a = 32;
int b = 128;
int foo = (a + b) | 255;

Here is some more info on Java primitive types http://mindprod.com/jgloss/primitive.html 以下是有关Java原始类型http://mindprod.com/jgloss/primitive.html的更多信息

One last trivial note, there is one unsigned fixed precision number in Java. 最后一个简单的注释,Java中有一个无符号的固定精度数。 That is the char primitive. 那是char原语。

I know this is a very late response, but I came across this thread when trying to do the exact same thing. 我知道这是一个非常晚的回应,但是在尝试做同样的事情时我遇到了这个问题。 The issue is simply trying to determine if a Java byte is >127. 问题只是试图确定Java字节是否> 127。

The simple solution is: 简单的解决方案是:

if((val & (byte)0x80) != 0) { ... }

If the real issue is >128 instead, just adding another condition to that if-statement will do the trick. 如果真正的问题是> 128,那么只需在if语句中添加另一个条件即可。

I guess you could just use a short to store them. 我想你可以用一个短片来存储它们。 Not very efficient, but really the only option besides some herculean effort that I have seen. 不是很有效率,但除了我所看到的一些艰巨的努力之外,它真的是唯一的选择。

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

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