Can we make unsigned byte in Java
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".
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:
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"
}
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
):
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 a different integral type, like short
, int
or long
.
Complete guide for working with unsigned bytes in Java:
Unsigned byte in Java
(Source for this answer.)
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.
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.
Here are a couple of useful conversions / manipulations for your convenience:
Conversions to / from 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
.)
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:
// 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));
There are no primitive unsigned bytes in Java. The usual thing is to cast it to bigger type:
int anUnsignedByte = (int) aSignedByte & 0xff;
I think the other answers have covered memory representation and how you handle these depends on the context of how you plan on using it. I'll add that Java 8 added some support for dealing with unsigned types. In this case, you could use Byte.toUnsignedInt
int unsignedInt = Byte.toUnsignedInt(myByte);