JAVA has no Unsigned Byte!!#$@$@#
Personally, i think in unsigned bytes…
Recently, i got involved in a project that we used Java for… but i ended up having to do a lot of low level bit packing and creating CRCs, etc.
At first when i realized that Java had no unsigned byte i started looking all over the web for an unsigned byte class. I found a few… but it wasn’t what i wanted. In the end i just faced my fear and started messing around with it… and what better way to do so but create a quick unit test TestCase.
if you read this poorly written unit test it might demystify things for you . If not, let me know what it needs to make you understand.
/*
* @author Blake Robertson (blaker@ieee.org)
* Created on Jan 22, 2006
*
* Using this test case i came to the following conclusions about
* when you can and when you can't use the java byte primitive when
* what you really want is a unsigned byte.
*
* CONCLUSIONS
* 1) If you want an unsigned byte and plan to use it to do arthmetic
* then don't! Because, once you get to 128 you no longer have a positive number
* you are doing math with... so what i do is i just use int's instead
* and i'm careful about not letting the value get bigger then 255.
*
* 2) Casting to byte does what it should... so if you have
* byte x = (byte) 0x23426463498242343699
* x= 0x99 (it always equals the lowest byte, the rest is trunkcated).
*
*
* 3) If you are only doing bit manipulation... then you are okay.
* you don't have to think about whether or not you are manipulating
* a signed or unsigned byte.... but if you have to print that number out
* then you might have a problem or if you need to compare that number.
*
*
* 4) So downcasting works like we want it to... we get whatever the lower
* byte is of int. So, i tested upcasting like from a byte to an int.
* Does it perform a sign extention or does it simply take the 1 byte that
* is set in the byte and set it in the int.
* Ans: it does sign extention so it keeps the number the same.
* EX: So for example byte b = -1 ...
* assertTrue( -1 == (int) b ); // doesn't cause errors (see one of the test cases below).
*
*
*
*
*
*
*/
package com.blakerobertson.test;
import com.blakerobertson.util.ByteUtil;
import junit.framework.TestCase;
/**
* Filename: JavaBitManipulationTestCase.java <BR>
* Date Created: Jan 22, 2006 <BR>
* <P>
*
* <P>
* @author blake
* @version 1.0
*
*/
public class JavaBitManipulationTestCase extends TestCase {
public void testWhatCastingDoes() {
int xInt = 0xFFFFFFFF;
short xShort = (short) xInt;
assertFalse( xShort == 0xFFFF );
assertTrue( xShort == (short) 0xFFFF );
assertTrue( xShort == ByteUtil.convertToSignedShort( 0xFFFF ).shortValue() );
// So, the cast is done properly... meaning the lower two bytes of it are
// set to the shorts 2 bytes... but when you want to actually print or compare the
}
public void testFlippingSignBit() {
byte x = 0;
byte y;
x = (byte) ( x | 0x80);
y = (byte) 0x80;
assertTrue( x == y );
}
public void testCasting2() {
int x = 255;
int xTwos = ~255 + 1;
int negX = -1;
int negXTwos = ~negX + 1;
// if the bits don't get changed when you cast it to a lower type at all.
// Then if i take 255 which is (1111 1111)base2 when i case it to a byte
// it should be equal to -1.
byte isNegOne = (byte) x;
byte negOne = -1;
assertTrue( negOne == isNegOne );
}
public void testIncrementingOverflow() {
byte x = 125;
// NO Exception is called... which was a suprise to me...
// try {
x++; // x = 126
x++; // x = 127
x++; // x = 128
assertTrue( x == (byte) 128 );
// }
// catch (Exception e) {
// return;
// }
}
public void testIsConvertToSignedByteUseless() {
for( int i=0; i < 256; i++ )
{
assertTrue( (byte) i == ByteUtil.convertToSignedByte( i ).byteValue() );
}
}
public void testNeedToConvertWhenByteShouldBeUnsigned() {
byte x = (byte) 200;
short y = 200;
int rand = 342;
assertFalse( (rand ^ x ) == (rand ^ y) );
// TODO determine why the assertion below fails
// assertTrue( (rand ^ ByteUtil.convertToUnsignedByte(x) ) == (rand ^ y) );
}
public void testCastByteToInt() {
byte theByte = (byte) 0xFF;
System.out.println("theByte == " + theByte ); // prints theByte == -1
int theInt = (int) theByte;
assertFalse( theInt == 255 );
assertTrue( theInt == -1 );
}
public static void main(String[] args) {
junit.swingui.TestRunner.run(JavaBitManipulationTestCase.class);
}
}
