Is there any provision of Unsigned byte in Java? [duplicate] - java

This question already has answers here:
Can we make unsigned byte in Java
(17 answers)
Closed 6 years ago.
When I XOR a byte lets say -1(in byte) with 2(int) I get -3 as a result whereas I want the operation to give me a positive int. This is due to the 2's complement representation and type promotion. I want to know if there a way I can use unsigned byte in java.
int x = 2;
byte y = -1;
System.out.println(x^y);
Output
-3
I found two excellent similar questions here and here. But I want some method or bitwise operation to return an int which can be later converted into byte without 2's complement representation.

All types except char (and boolean) are signed.
To get an unsigned-equivalent value, you can use a wider type and use a mask:
public static int unsigned(byte value) {
return value & 0xff;
}
public static int unsigned(short value) {
return value & 0xffff;
}
public static long unsigned(int value) {
return value & 0xffffffffl;
}
Since Java 8, the standard API provides methods for that (e.g. Byte.toUnsignedInt(…)).

The only unsigned type in Java is a char, which is a 16 bit unsigned integer.
You could make use of that.
Mask away the more significant bytes using & 0xff if you need to.

Related

short to int cast, weird behaviour

I currently read from a ByteBuffer a short value and apply it to an int.
byte[] data = new byte{0x90, 0xAF};
ByteBuffer b = ByteBuffer.wrap(data);
int value = b.getShort();
but the value contains now 0xFFFF90AF and not 0x90AF.
My solution is to bitmask the value by 0xFFFF: int value = b.getShort() & 0xFFFF;
I thought that a upcast is always possible, because short is smaller than int. Can someone explain why it behaves like this?
short is signed, and that is preserved when casting to int. 0x90AF is a negative short, so the result is negative int. Your solution of masking it is correct.
short is a signed quantity, but you are in luck: there is also char, which is the only unsigned primitive type in Java, and is the same size as short. Try to use
int value = b.getChar();
It is an often neglected fact that char is a full-blown numeric type in Java; it is only its string representation which betrays its special status.

Java and unsigned Bytes [duplicate]

This question already has answers here:
What is the best way to work around the fact that ALL Java bytes are signed?
(7 answers)
Closed 4 years ago.
I need to make use of an array of unsigned bytes. I need to send certain characters over the network to a server and some of these characters are greater that 127.
I have a simplified version of the code below to try and understand the concept:
int i= 160;
byte j = (byte) i;
System.out.println((byte)i);
System.out.println(j);
and this gives an output of:
-96
-96
I need to print 160. As the server is expecting a byte of 160 and if it receives -96 it does not accept the value. The reason I used an int is that when I was reading how to get around the problem, I often came across the suggestion to just use an int, but I don't quite understand that, as I need my array to be of type byte.
This is the part of my code where I send the array:
public boolean send(byte[] data) {
try {
out.write(data); // Write the data to the outStream
out.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false; // Return false if the TCP Transmit failed
// }
return false;
}
I would really appreciate it if some one could help me.
There is no distinction in Java between signed and unsigned bytes. Both of the following will assign the same value to a byte:
byte i = (byte)160;
byte j = (byte)-96;
Its up to you as a developer to treat them as signed or unsigned when you print them out. The default is to print them signed, but you can force them to print unsigned by converting them to an integer in an unsigned manner.
System.out.println(i); // -96
System.out.println(0xff&i); // 160
If you want to know how bytes can represent both negative and positive numbers at the same time, read this article on two’s complement arithmetic in Java
Sending -96 is the correct behavior. Signed and unsigned bytes are different when they're printed out, but not in the bit representation, and they should not make a difference when they are received by another server.
There is no System.out.println(byte). The closest is System.out.println(int). This means your byte values are converted to ints. The conversion extends the high bit, resulting in a negative number.
This following code will demonstrate my point:
byte[] data =
{
(byte)0x01,
(byte)0x02,
(byte)0x7F,
(byte)0x80
};
for (byte current : data)
{
String output = String.format("0x%x, 0x%x", current, (int)current);
System.out.println(output);
}
If you want to use System.out.println to see your byte values, mask off the top three bytes of the integer value, something like this:
System.out.println(((0x000000FF & (int)current);
Bytes are not signed or unsigned by themselves. They are interpreted as such when some operations are applied (say, compare to 0 to determine sign). The operations can be signed and unsigned, and in Java, only signed byte operations are available. So the code you cited is useless for the question - it sends bytes but does not do any operation. Better show the code which receives bytes. One correct and handy method is to use java.io.InputStream.read() method which returns byte as an integer in the range 0...255.

Parsing big hexadecimal numbers in Java

I'm trying to parse into int a String which is hexadecimal number in my code (FF00FF00, for example) using Integer.parseInt(String string, int radix), but always get NumberFormatException. If I parse the number without last two numbers (FF00FF) it works well.
Is there any method to parse such big numbers in Java?
If Integer is too small, use Long:
Long.parseLong(string, 16)
If Long is still too small, use BigInteger:
new BigInteger(string, 16)
I would use Long.parseLong(x, 16) BigInteger is overkill for a 32-bit value.
If you expect this value to be an int value you can cast the result.
int x = (int) Long.parseLong("FF00FF00", 16);

hex to int number format exception in java

I am getting a number format exception when trying to do it
int temp = Integer.parseInt("C050005C",16);
if I reduce one of the digits in the hex number it converts but not otherwise. why and how to solve this problem?
This would cause an integer overflow, as integers are always signed in Java. From the documentation of that method (emphasis mine):
An exception of type NumberFormatException is thrown if any of the following situations occurs:
The first argument is null or is a string of length zero.
The radix is either smaller than Character.MIN_RADIX or larger than Character.MAX_RADIX.
Any character of the string is not a digit of the specified radix, except that the first character may be a minus sign '-' ('\u002D') provided that the string is longer than length 1.
The value represented by the string is not a value of type int.
It would fit into an unsigned integer, though. As of Java 8 there's Integer.parseUnsignedInt (thanks, Andreas):
int temp = Integer.parseIntUnsigned("C050005C",16);
On earlier Java versions your best bet here might to use a long and then just put the lower 4 bytes of that long into an int:
long x = Long.parseLong("C050005C", 16);
int y = (int) (x & 0xffffffff);
Maybe you can even drop the bitwise "and" here, but I can't test right now. But that could shorten it to
int y = (int) Long.parseLong("C050005C", 16);
C050005C is 3226468444 decimal, which is more than Integer.MAX_VALUE. It won't fit in int.
Use this:
long temp = Long.parseLong("C050005C",16);
The signed int type ranges from 0x7FFFFFFF to -0x80000000.

Increment a Hex value (JAVA)

can you increment a hex value in Java? i.e. "hex value" = "hex value"++
It depends how the hex value is stored. If you've got the hex value in a string, convert it to an Integer, increment and convert it back.
int value = Integer.parseInt(hex, 16);
value++;
String incHex = Integer.toHexString(value);
Short answer: yes. It's
myHexValue++;
Longer answer: It's likely your 'hex value' is stored as an integer. The business of converting it into a hexadecimal (as opposed to the usual decimal) string is done with
Integer.toHexString( myHexValue )
and from a hex string with
Integer.parseInt( someHexString, 16 );
M.
What do you mean with "hex value"? In what data type is your value stored?
Note that int/short/char/... don't care how your value is represented initially:
int i1 = 0x10;
int i2 = 16;
i1 and i2 will have the exact same content. Java (and most other languages as well) don't care about the notation of your constants/values.
Yes. All ints are binary anyway, so it doesn't matter how you declare them.
int hex = 0xff;
hex++; // hex is now 0x100, or 256
int hex2 = 255;
hex2++; // hex2 is now 256, or 0x100
The base of the number is purely a UI issue. Internally an integer is stored as binary. Only when you convert it to human representation do you choose a numeric base. So you're question really boils down to "how to increment an integer?".

Categories