解决所有Java字节都签名的最佳方法是什么?

解决所有Java字节都签名的最佳方法是什么?

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

在Java中,没有无符号字节之类的东西。

使用一些低级代码,有时您需要使用无符号值大于128的字节,由于MSB被用作符号,因此Java会将其解释为负数。

解决此问题的好方法是什么? (说不使用Java不是一种选择)


如果您这样做,实际上可以摆脱if语句和加法。

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

这样,Java不会将字节解释为负数,也不会翻转整数上的符号位。


从数组中读取任何单个值时,请将其复制到short或int之类的值中,然后将负数手动转换为正值。

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

写入数组时,可以执行类似的转换。


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


我知道这是一个很晚的响应,但是当我尝试做完全相同的事情时遇到了这个线程。问题只是试图确定Java字节是否大于127。

简单的解决方案是:

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

如果实际问题是> 128,则只需在该if语句中添加另一个条件即可解决问题。


进行位操作/无符号字节的最佳方法是使用整数。即使它们是有符号的,它们也有许多备用位(总共32个)被视为无符号字节。同样,所有数学运算符都会将较小的固定精度数字转换为int。例:

1
2
3
4
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

因此,最好只是坚持使用整数并将其屏蔽以获取您感兴趣的位。示例:

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

这是有关Java基本类型的更多信息http://mindprod.com/jgloss/primitive.html

最后一点,在Java中有一个无符号的固定精度数字。那就是char原语。


最好的选择是使用整数而不是字节。它有空间允许大于128的数字,而不必创建特殊对象来替换字节的开销。

比我聪明的人(所有人)也建议这样做

  • http://www.darksleep.com/player/JavaAndUnsignedTypes.html
  • http://www.jguru.com/faq/view.jsp?EID=13647


我想你可以用一个短裤来存储它们。效率不是很高,但是除了我所看到的一些艰巨的努力,它实际上是唯一的选择。


推荐阅读