我们可以在 Java 中创建无符号字节吗
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4266756/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can we make unsigned byte in Java
提问by dln
I am trying to convert a signed byte in unsigned. The problem is the data I am receiving is unsigned and Java does not support unsigned byte, so when it reads the data it treats it as signed.
我正在尝试将有符号字节转换为无符号字节。问题是我收到的数据是无符号的,Java 不支持无符号字节,所以当它读取数据时,它把它当作有符号的。
I tried it to convert it by the following solution I got from Stack Overflow.
我尝试通过以下从 Stack Overflow 获得的解决方案来转换它。
public static int unsignedToBytes(byte a)
{
int b = a & 0xFF;
return b;
}
But when again it's converted in byte, I get the same signed data. I am trying to use this data as a parameter to a function of Java that accepts only a byte as parameter, so I can't use any other data type. How can I fix this problem?
但是当它再次按字节转换时,我得到相同的签名数据。我试图将此数据用作只接受一个字节作为参数的 Java 函数的参数,因此我不能使用任何其他数据类型。我该如何解决这个问题?
采纳答案by Guillaume
I'm not sure I understand your question.
我不确定我是否理解你的问题。
I just tried this and for byte -12 (signed value) it returned integer 244 (equivalent to unsigned byte value but typed as an int
):
我刚刚尝试过这个,对于字节 -12(有符号值),它返回整数 244(相当于无符号字节值,但输入为int
):
public static int unsignedToBytes(byte b) {
return b & 0xFF;
}
public static void main(String[] args) {
System.out.println(unsignedToBytes((byte) -12));
}
Is it what you want to do?
这是你想做的吗?
Java does not allow to express 244 as a byte
value, as would C. To express positive integers above Byte.MAX_VALUE
(127) you have to use an other integer type, like short
, int
or long
.
Java 不允许将 244 表示为byte
值,就像 C 一样。要表示Byte.MAX_VALUE
(127)以上的正整数,您必须使用其他整数类型,例如short
,int
或long
。
回答by Peter Lawrey
If you have a function which must be passed a signed byte, what do you expect it to do if you pass an unsigned byte?
如果您有一个函数必须传递一个有符号字节,那么如果传递一个无符号字节,您希望它做什么?
Why can't you use any other data type?
为什么不能使用任何其他数据类型?
Unsually you can use a byte as an unsigned byte with simple or no translations. It all depends on how it is used. You would need to clarify what you indend to do with it.
不寻常的是,您可以将一个字节用作无符号字节,并进行简单的翻译或不进行翻译。这一切都取决于它的使用方式。你需要澄清你打算用它做什么。
回答by Adamski
The fact that primitives are signed in Java is irrelevant to how they're represented in memory / transit - a byte is merely 8 bits and whether you interpret that as a signed range or not is up to you. There is no magic flag to say "this is signed" or "this is unsigned".
原语在 Java 中签名的事实与它们在内存/传输中的表示方式无关 - 一个字节只有 8 位,您是否将其解释为有符号范围取决于您。没有魔术标志可以说“这是已签名”或“这是未签名”。
As primitives are signed the Java compiler will prevent you from assigning a value higher than +127 to a byte (or lower than -128). However, there's nothing to stop you downcasting an int (or short) in order to achieve this:
由于原语被签名,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"
}
回答by aioobe
The Java Language does not provide anything like the unsigned
keyword. A byte
according to the language spec represents a value between −128 - 127. For instance, if a byte
is cast to an int
Java will interpret the first bit as the sign and use sign extension.
Java 语言不提供类似unsigned
关键字的任何内容。Abyte
根据语言规范表示 -128 - 127 之间的值。例如,如果 abyte
被强制转换为int
Java 会将第一位解释为符号并使用符号扩展。
That being said, nothing prevents you from viewing a byte
simply as 8 bits and interpret those bits as a value between 0 and 255. Just keep in mind that there's nothing you can do to force your interpretation upon someone else's method. If a method accepts a byte
, then that method accepts a value between −128 and 127 unless explicitly stated otherwise.
话虽如此,没有什么能阻止您将 abyte
简单地视为 8 位并将这些位解释为 0 到 255 之间的值。请记住,您无法将您的解释强加于其他人的方法。如果一个方法接受 a byte
,则该方法接受一个介于 -128 和 127 之间的值,除非另有明确说明。
Here are a couple of useful conversions / manipulations for your convenience:
为了您的方便,这里有几个有用的转换/操作:
Conversions to / from 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
(Or, if you're on Java 8+, use Byte.toUnsignedInt
.)
(或者,如果您使用的是 Java 8+,请使用Byte.toUnsignedInt
.)
Parsing / formatting
解析/格式化
Best way is to use the above conversions:
最好的方法是使用上述转换:
// Parse an unsigned byte
byte b = (byte) Integer.parseInt("200");
// Print an unsigned byte
System.out.println("Value of my unsigned byte: " + (b & 0xFF));
Arithmetics
算术
The 2-complement representation "just works" for addition, subtraction and multiplication:
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
Division requires manual conversion of operands:
除法需要手动转换操作数:
byte ratio = (byte) ((b1 & 0xFF) / (b2 & 0xFF));
回答by Peter Knego
There are no primitive unsigned bytes in Java. The usual thing is to cast it to bigger type:
Java 中没有原始的无符号字节。通常的做法是将其转换为更大的类型:
int anUnsignedByte = (int) aSignedByte & 0xff;
回答by Pritesh Jain
回答by Kyle Kinkade
A side note, if you want to print it out, you can just say
附注,如果你想打印出来,你可以说
byte b = 255;
System.out.println((b < 0 ? 256 + b : b));
回答by XapaJIaMnu
If you want unsigned bytes in Java, just subtract 256 from the number you're interested in. It will produce two's complementwith a negative value, which is the desired number in unsigned bytes.
如果你想在 Java 中使用无符号字节,只需从你感兴趣的数字中减去 256。它会产生一个负值的二进制补码,这是所需的无符号字节数。
Example:
例子:
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.
You need to use such dirty hacks when using leJOSto program the NXT brick.
回答by Bob
Although it may seem annoying (coming from C) that Java did not include unsigned byte in the language it really is no big deal since a simple "b & 0xFF" operation yields the unsigned value for (signed) byte b in the (rare) situations that it is actually needed. The bits don't actually change -- just the interpretation (which is important only when doing for example some math operations on the values).
尽管 Java 没有在语言中包含无符号字节这似乎很烦人(来自 C),但这确实没什么大不了的,因为简单的“b & 0xFF”操作会在(罕见的)中产生(有符号)字节 b 的无符号值实际需要的情况。这些位实际上并没有改变——只是解释(这只有在对值进行一些数学运算时才很重要)。
回答by Ewe Loon
Adamski provided the best answer, but it is not quite complete, so read his reply, as it explains the details I'm not.
Adamski 提供了最好的答案,但还不够完整,所以请阅读他的回复,因为它解释了我不知道的细节。
If you have a system function that requires an unsigned byte to be passed to it, you can pass a signed byte as it will automatically treat it as an unsigned byte.
如果您的系统函数需要将无符号字节传递给它,则可以传递有符号字节,因为它会自动将其视为无符号字节。
So if a system function requires four bytes, for example, 192 168 0 1 as unsigned bytes you can pass -64 -88 0 1, and the function will still work, because the act of passing them to the function will un-sign them.
因此,如果系统函数需要四个字节,例如 192 168 0 1 作为无符号字节,您可以传递 -64 -88 0 1,该函数仍然可以工作,因为将它们传递给函数的行为将取消对它们的签名.
However you are unlikely to have this problem as system functions are hidden behind classes for cross-platform compatibility, though some of the java.io read methods return unsighed bytes as an int.
但是,您不太可能遇到这个问题,因为系统函数隐藏在跨平台兼容性的类之后,尽管一些 java.io 读取方法将未叹气的字节作为 int 返回。
If you want to see this working, try writing signed bytes to a file and read them back as unsigned bytes.
如果你想看到这个工作,尝试将有符号字节写入文件并将它们作为无符号字节读回。