Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我们可以在Java中生成无符号字节吗_Java_Unsigned - Fatal编程技术网

我们可以在Java中生成无符号字节吗

我们可以在Java中生成无符号字节吗,java,unsigned,Java,Unsigned,我正在尝试将有符号字节转换为无符号字节。问题是我接收的数据是无符号的,Java不支持无符号字节,所以当它读取数据时,它将其视为有符号的 我尝试用StackOverflow提供的以下解决方案来转换它 public static int unsignedToBytes(byte a) { int b = a & 0xFF; return b; } 但当它再次转换成字节时,我得到的是相同的有符号数据。我试图将此数据用作Java函数的参数,该函数只接受一个字节作为参数,因此我不

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

我尝试用StackOverflow提供的以下解决方案来转换它

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

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

如果您有一个必须传递有符号字节的函数,那么如果传递无符号字节,您希望它做什么

为什么不能使用任何其他数据类型


不确切地说,您可以将一个字节用作简单或无翻译的无符号字节。这完全取决于如何使用它。您需要澄清您打算如何使用它。

原语在Java中有符号这一事实与它们在内存/传输中的表示方式无关-一个字节仅为8位,您是否将其解释为有符号范围取决于您自己。没有魔法旗可以说“这是签名的”或“这是未签名的”

由于对原语进行了签名,Java编译器将阻止您将大于+127的值分配给一个字节(或小于-128)。但是,为了实现这一点,没有什么可以阻止您向下转换int(或short):

int i = 200; // 0000 0000 0000 0000 0000 0000 1100 1000 (200)
byte b = (byte) 200; // 1100 1000 (-56 by Java specification, 200 by convention)

/*
 * Will print a negative int -56 because upcasting byte to int does
 * so called "sign extension" which yields those bits:
 * 1111 1111 1111 1111 1111 1111 1100 1000 (-56)
 *
 * But you could still choose to interpret this as +200.
 */
System.out.println(b); // "-56"

/*
 * Will print a positive int 200 because bitwise AND with 0xFF will
 * zero all the 24 most significant bits that:
 * a) were added during upcasting to int which took place silently
 *    just before evaluating the bitwise AND operator.
 *    So the `b & 0xFF` is equivalent with `((int) b) & 0xFF`.
 * b) were set to 1s because of "sign extension" during the upcasting
 *
 * 1111 1111 1111 1111 1111 1111 1100 1000 (the int)
 * &
 * 0000 0000 0000 0000 0000 0000 1111 1111 (the 0xFF)
 * =======================================
 * 0000 0000 0000 0000 0000 0000 1100 1000 (200)
 */
System.out.println(b & 0xFF); // "200"

/*
 * You would typically do this *within* the method that expected an 
 * unsigned byte and the advantage is you apply `0xFF` only once
 * and than you use the `unsignedByte` variable in all your bitwise
 * operations.
 *
 * You could use any integer type longer than `byte` for the `unsignedByte` variable,
 * i.e. `short`, `int`, `long` and even `char`, but during bitwise operations
 * it would get casted to `int` anyway.
 */
void printUnsignedByte(byte b) {
    int unsignedByte = b & 0xFF;
    System.out.println(unsignedByte); // "200"
}

Java中使用无符号字节的完整指南:

(此答案的来源。)


Java语言不提供类似于
unsigned
关键字的任何内容。根据语言规范,字节表示介于−128 - 127. 例如,如果将
字节
转换为
int
Java将第一位解释为符号并使用

也就是说,没有什么可以阻止您将
字节
简单地看作8位,并将这些位解释为0到255之间的值。请记住,你无法将你的解释强加给其他人的方法。如果一个方法接受一个
字节
,那么该方法接受一个介于−128和127,除非另有明确说明

为了方便您,这里有几个有用的转换/操作:

与int的转换
(或者,如果您使用的是Java 8+,请使用。)

解析/格式化 最好的方法是使用上述转换:

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

算术 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));

我不确定我是否理解你的问题

我刚刚尝试了这个方法,对于字节-12(有符号值),它返回了整数244(相当于无符号字节值,但键入的是
int
):

这是你想做的吗


Java不允许将244表示为
字节
值,就像C一样。要在
字节上表示正整数。MAX_value
(127)必须使用不同的整数类型,如
short
int
long
Java中没有原始的无符号字节。通常的做法是将其转换为更大的类型:

int anUnsignedByte = (int) aSignedByte & 0xff;

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

一个旁注,如果你想打印出来,你可以说

byte b = 255;
System.out.println((b < 0 ? 256 + b : b));
字节b=255;
系统输出println((b<0?256+b:b));

如果您想要Java中的无符号字节,只需从您感兴趣的数字中减去256即可。它将产生一个负值,这是所需的无符号字节数

例如:

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.

当使用来编程时,您需要使用这些肮脏的黑客。

尽管Java在语言中没有包含无符号字节看起来很烦人(来自C),但这其实没什么大不了的,因为一个简单的“b&0xFF”操作在实际需要的(罕见)情况下为(有符号)字节b生成无符号值。位实际上不会改变——只是解释(这仅在对值进行一些数学运算时才重要)。

亚当斯基提供了最佳答案,但答案并不完全,所以请阅读他的回答,因为它解释了我不知道的细节

如果系统函数需要向其传递无符号字节,则可以传递有符号字节,因为它会自动将其视为无符号字节

因此,如果一个系统函数需要四个字节,例如,192 168 01作为无符号字节,则可以传递-64-88 01,该函数仍然可以工作,因为将它们传递给函数的行为将取消对它们的签名

然而,您不太可能遇到这个问题,因为为了跨平台兼容性,系统函数隐藏在类后面,尽管一些java.io读取方法返回未升级的字节作为int


如果您想看到这一点,请尝试将有符号字节写入文件,并将其作为无符号字节读回。

如果您认为您正在寻找类似的内容

public static char toUnsigned(byte b) {
    return (char) (b >= 0 ? b : 256 + b);
}

Java中没有无符号字节,但如果要显示字节,可以

int myInt = 144;

byte myByte = (byte) myInt;

char myChar = (char) (myByte & 0xFF);

System.out.println("myChar :" + Integer.toHexString(myChar));
输出:

myChar : 90

有关更多信息,请检查。

我认为其他答案已经涵盖了内存表示,您如何处理这些问题取决于您计划如何使用它的上下文。我要补充一点。在这种情况下,您可以使用

int unsignedInt=Byte.toUnsignedInt(myByte);

是和否。我一直在研究这个问题。 就像我理解的那样:

事实上,java已经将INTEGER-128签名为127。。 可以使用以下内容在java中显示未签名的文件:

public static int toUnsignedInt(byte x) {
    return ((int) x) & 0xff;
}
例如,如果您将-12有符号数字添加为无符号数字,则得到244。但是你可以在signed中再次使用这个数字,它必须被移回signed,它将再次是-12

如果您尝试将244添加到java字节,您将得到outOfIndexException

public static char toUnsigned(byte b) {
    return (char) (b >= 0 ? b : 256 + b);
}
int myInt = 144;

byte myByte = (byte) myInt;

char myChar = (char) (myByte & 0xFF);

System.out.println("myChar :" + Integer.toHexString(myChar));
myChar : 90
public static int toUnsignedInt(byte x) {
    return ((int) x) & 0xff;
}
public static int unsignedToBytes(byte a)
{
    return (int) ( ( a << 24) >>> 24);
}