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); } }