我试图转换一个无符号的有符号字节。问题是我接收的数据是无符号的,Java不支持无符号字节,所以当它读取数据时,它将其视为有符号的。

我尝试通过下面的解决方案转换它,我从Stack Overflow。

public static int unsignedToBytes(byte a)
{
    int b = a & 0xFF;
    return b;
}

但是当它再次以字节为单位转换时,我得到了相同的带符号数据。我试图使用此数据作为参数的Java函数,只接受一个字节作为参数,所以我不能使用任何其他数据类型。我该如何解决这个问题?


当前回答

由于Java中的限制,无符号字节在当前的数据类型格式中几乎是不可能的。你可以为你要实现的东西使用其他语言的其他库,然后你可以使用JNI调用它们。

其他回答

如果您想在Java中使用无符号字节,只需从感兴趣的数字中减去256。它将生成带有负值的2的补数,这是所需的无符号字节数。

例子:

int speed = 255; //Integer with the desired byte value
byte speed_unsigned = (byte)(speed-256);
//This will be represented in two's complement so its binary value will be 1111 1111
//which is the unsigned byte we desire.

在使用leJOS编程NXT块时,您需要使用这种肮脏的技巧。

我认为其他答案已经涵盖了内存表示,您如何处理这些取决于您计划如何使用它的上下文。我要补充的是,Java 8增加了一些处理无符号类型的支持。在这种情况下,您可以使用Byte.toUnsignedInt

int unsignedInt = Byte.toUnsignedInt(myByte);

顺便说一句,如果你想打印出来,你可以说

byte b = 255;
System.out.println((b < 0 ? 256 + b : b));

在Java中使用unsigned字节的完整指南:

Java中的无符号字节

(答案来源)


Java语言不提供任何类似unsigned关键字的东西。根据语言规范,一个字节表示−128 - 127之间的值。例如,如果将一个字节转换为int类型,Java将把第一位解释为符号并使用符号扩展。

也就是说,没有什么可以阻止您将一个字节简单地视为8位,并将这些位解释为0到255之间的值。只要记住,你不能把你的解释强加给别人的方法。如果一个方法接受一个字节,那么该方法接受−128到127之间的值,除非另有明确说明。

下面是一些有用的转换/操作,方便您使用:

从int到int的转换

// From int to unsigned byte
int i = 200;                    // some value between 0 and 255
byte b = (byte) i;              // 8 bits representing that value

// From unsigned byte to int
byte b = 123;                   // 8 bits representing a value between 0 and 255
int i = b & 0xFF;               // an int representing the same value

(或者,如果你使用的是Java 8+,使用Byte.toUnsignedInt。)

解析/格式化

最好的方法是使用上面的转换:

// Parse an unsigned byte
byte b = (byte) Integer.parseInt("200");

// Print an unsigned byte
System.out.println("Value of my unsigned byte: " + (b & 0xFF));

算法

2补表示“只适用于”加法、减法和乘法:

// two unsigned bytes
byte b1 = (byte) 200;
byte b2 = (byte) 15;

byte sum  = (byte) (b1 + b2);  // 215
byte diff = (byte) (b1 - b2);  // 185
byte prod = (byte) (b2 * b2);  // 225

除法需要手动转换操作数:

byte ratio = (byte) ((b1 & 0xFF) / (b2 & 0xFF));

在好奇netty ByteBuf writeInt和readUnsignedInt方法的明显不对称之后,我碰巧偶然地进入了这个页面。

在阅读了有趣和有教育意义的答案后,我仍然想知道你说的时候调用的是什么函数:

我试图使用这些数据作为参数的Java函数 只接受一个字节作为参数。

不管这么多年过去了,我的50美分如下:

让我们假设您正在调用的方法正在用微量更新一些余额,并且它根据一些定义良好的需求集进行操作。也就是说,它被认为对其预期的行为有正确的实现:

long processMicroPayment(byte amount) {
    this.balance += amount;
    return balance;     
}

Basically, if you supply a positive amount it will be added to the balance, and a negative amount will effectively be subtracted from the balance. Now because it accepts a byte as its parameter the implicit assumption is that it functionally only accepts amounts between -128 and +127. So if you want to use this method to add, say, 130 to the balance, it simply will not produce the result YOU desire, because there is no way within the implementation of this method to represent an amount higher than 127. So passing it 130 will not result in your desired behavior. Note that the method has no way of implementing a (say) AmountOutOfBoundsException because 130 will be 'interpreted' as a negative value that is still obeying the method's contract.

我有以下几个问题:

您是否根据其(隐式或显式)契约使用该方法? 方法是否正确实现? 我还是误解了你的问题吗?