1

I have a byte array:

byte[] a = new byte[3];

which I have added some bytes. For this example, let's say 3, 4, and 210.

I would like to print this string of bytes to look like 3 4 210, but instead I get 3 4 -46

I am using String.valueOf(a[i]) to do my conversion. Is there any way to force this conversion to give unsigned values?

Thanks in advance,

EDIT: Thanks to the various feedback on this question. I had not realized Java Bytes were signed values by default, and so was suspecting the String.valueOf() method as being the issue. It turns out just simply using

String.valueOf(a[i]&0xFF)

takes care of the signed formatting issue.

Again, thank you for your feedback!

Nanomurf
  • 709
  • 3
  • 12
  • 32
  • There is no unsigned type in Java. If you want that to print `210`, then why not just take an `int[]`? – Rohit Jain Feb 14 '14 at 04:38
  • Thank you for your time and feedback. I'm learning this Java one day at a time. I did not realize that Java bytes were signed. Let me go through the responses and process them... – Nanomurf Feb 14 '14 at 04:50

4 Answers4

3

Guava provides a UnsignedBytes class that can make that conversion. The static toString(byte) method

Returns a string representation of x, where x is treated as unsigned.

For example

System.out.println(UnsignedBytes.toString(a[i]));

where a[i] = -46 would print

210

Internally, all this does is call

public static int toInt(byte value) {
    return value & UNSIGNED_MASK; // UNSIGNED_MASK = 0xFF
}

and convert the int to a String which it returns.


For an explanation

With

someByte & 0xFF

since OxFF is an integer literal, the someByte value is widened to an int. Let's take for example the value -46. Its binary representation is

11111111111111111111111111010010

The binary representation of 0xFF is

11111111 // ie 255

if you and & the two

11111111111111111111111111010010
00000000000000000000000011111111 
--------------------------------
00000000000000000000000011010010

which is equal to

210

Basically you only keep the lower 8 bits of the int.

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
1

Java byte data type range is minimum value of -128 and a maximum value of 127 (inclusive). String.valueOf(a[i]) doesn't do this conversion. Use int type instead.

Abimaran Kugathasan
  • 31,165
  • 11
  • 75
  • 105
1

byte byte range limit is within -128 to 127, so for 210 it gives -46. so convert it using int type

Nambi
  • 11,944
  • 3
  • 37
  • 49
  • 2
    You've described the problem, but it looks like the OP already knew this. Do you have any suggestions for a solution? – user2357112 Feb 14 '14 at 04:40
1

You've run into Java's famous problem of bytes treated as signed even though most of the real world prefers these unsigned. Try this:

int[] signedArr = new int[a.length];
for (int i=0; i<a.length; ++i) {
  signedArr[i] = a[i] & 0xff;
}

Then you can work with signedArr.

seand
  • 5,168
  • 1
  • 24
  • 37