In the last month or so I've been spending a lot of time playing with protocols in Java. Having previously done this kind of work in either .NET or C++ I had become accustomed to having unsigned data types available to me. So coming to Java I was a little shocked that they were missing. This seems somewhat accepted in the Java community so I am, of course, going with the flow.
Despite Java having some very useful classes like the java.io ByteArrayInputStream and ByteArrayOutputStream I found very little information out there on what exactly happens when you want to read or write unsigned byte values. So I wrote a little bit of test code to prove that my understanding was correct:
int in, out;
byte b;
in = 0;
b = (byte)in;
out = b & 0xff;
System.out.println("in=" + in + ", b=" + b + ", out=" + out);
in = 127;
b = (byte)in;
out = b & 0xff;
System.out.println("in=" + in + ", b=" + b + ", out=" + out);
in = 128;
b = (byte)in;
out = b & 0xff;
System.out.println("in=" + in + ", b=" + b + ", out=" + out);
in = 255;
b = (byte)in;
out = b & 0xff;
System.out.println("in=" + in + ", b=" + b + ", out=" + out);
Which produces the following output to the Console:
in=0, b=0, out=0
in=127, b=127, out=127
in=128, b=-128, out=128
in=255, b=-1, out=255
Hopefully this might be of use to somebody. It certainly made me feel more at ease 'flinging them bytes about'!
Monday, 16 August 2010
Java unsigned int to signed byte and back again
Java String valueOf and StringBuilder append - int and char differences
I'm in the middle of writing some code which uses the InputStream read function. InputStream.read() returns a value of -1 when you get to the end of the stream but until that point it returns a byte (0 to 255).
I am pushing these bytes to a StringBuilder and wanted them to be interpreted as their ASCII character codes. What's not obvious from the documentation is that char is treated very differently from other numbers pushed to a StringBuilder with the append function.
The documentation for StringBuilder append(char) states: Appends the string representation of the specified char value. The char value is converted to a string according to the rule defined by valueOf(char).
The documentation for StringBuilder append(int) states: Appends the string representation of the specified int value. The int value is converted to a string according to the rule defined by valueOf(int).
Identical definitions!
The documentation for String valueOf(char) states: Converts the specified character to its string representation. Returns the character converted to a string.
The documentation for String valueOf(int) states: Converts the specified integer to its string representation. Returns the integer converted to a string.
Again, identical definitions. But...
This test code:
int a = 65;
int b = 66;
StringBuilder sb = new java.lang.StringBuilder();
sb.append("int a = [");
sb.append(a);
sb.append("], char a = [");
sb.append((char)a);
sb.append("], int b = [");
sb.append(b);
sb.append("], char b = [");
sb.append((char)b);
sb.append("]");
System.out.println(sb.toString());
Produces this console output:
int a = [65], char a = [A], int b = [66], char b = [B]
As tested against the Java SE 6 SDK.
Which confirms that StringBuilder append and String valueOf behave differently for int and char types. For my particular requirements here this is the behaviour I wanted - and logical enough to cast an int to char to get this behaviour. But to someone who might be coming from a different programming environment (say, for example, one with unsigned data types!) then this might not be so obvious - hence why I've posted this article!
I am pushing these bytes to a StringBuilder and wanted them to be interpreted as their ASCII character codes. What's not obvious from the documentation is that char is treated very differently from other numbers pushed to a StringBuilder with the append function.
The documentation for StringBuilder append(char) states: Appends the string representation of the specified char value. The char value is converted to a string according to the rule defined by valueOf(char).
The documentation for StringBuilder append(int) states: Appends the string representation of the specified int value. The int value is converted to a string according to the rule defined by valueOf(int).
Identical definitions!
The documentation for String valueOf(char) states: Converts the specified character to its string representation. Returns the character converted to a string.
The documentation for String valueOf(int) states: Converts the specified integer to its string representation. Returns the integer converted to a string.
Again, identical definitions. But...
This test code:
int a = 65;
int b = 66;
StringBuilder sb = new java.lang.StringBuilder();
sb.append("int a = [");
sb.append(a);
sb.append("], char a = [");
sb.append((char)a);
sb.append("], int b = [");
sb.append(b);
sb.append("], char b = [");
sb.append((char)b);
sb.append("]");
System.out.println(sb.toString());
Produces this console output:
int a = [65], char a = [A], int b = [66], char b = [B]
As tested against the Java SE 6 SDK.
Which confirms that StringBuilder append and String valueOf behave differently for int and char types. For my particular requirements here this is the behaviour I wanted - and logical enough to cast an int to char to get this behaviour. But to someone who might be coming from a different programming environment (say, for example, one with unsigned data types!) then this might not be so obvious - hence why I've posted this article!
Labels:
java
Subscribe to:
Posts (Atom)