/* File: UnsignedByte.java CVS Info: $Id: UnsignedByte.java,v 1.1.1.1 1998/01/27 22:48:51 mcgredo Exp $ Compiler: jdk 1.1.5 */ package mil.navy.nps.util; // package this belongs to import java.io.*; import java.lang.*; /** *@version 1.0 *@author Don McGregor (http://www.npsnet.org/~mcgredo) * *
* * Note that you can't retrieve the value of this as a byte, simply * because a negative value for an unsigned byte (as the signed value * 242 would be) is invalid, and can't be represented. So we have to * promote the bloody thing to an int.
* * Hmmmmm....should the internal representation be a short or a byte? * I vote for byte, since it requires less storage in memory, and we * might have a lot of these floating about. But we're constantly * promoting it to an int or short anyway...
* * This implementation works by exploiting the characteristics of how * numbers are stored internally. Just about all systems, except for a * few obsolete machines, use "two's-complement" format for storing * integer values. A signed byte will have this sequence as more and * more bits are flipped on:
* * 0,1,2,3....125,126,127,-128,-127,-127,...-1
*
* The values roll over from (2^7)-1 to -(2^7) at the midpoint. Adding
* one to 127 will result in -128, adding two results in -127, etc. We
* can fake up unsigned bytes by exploiting this behavior. The maximum
* an unsigned byte can represent is 255 (2^8 - 1) so we can translate
* between a negative value and its unsigned positive representation with
* this formula:
*
* which means that -128 is mapped to 128, -126 to 129, and so on.
*255 + _data + 1
*
* * This implements the Cloneable interface, which means that when we clone() * something we can do a bitwise field copy (shallow copy). This needs to * change if we ever have any actual objects contained in this class.
* *
UnsignedByte
object and intializes its value to 0.
*/
public UnsignedByte()
{
_data = 0;
}
/**
*Constructs an UnsignedByte
object from a signed byte,
*throws an exception if the paraneter is out of range.
*
*@param pData >=0
*@exception RuntimeException if pData
is out of range
*/
public UnsignedByte(byte pData)
{
if(pData < 0)
throw new
RuntimeException("Exception in UnsignedByte. Attempt to assign value beyond maximum range of an unsigned byte.");
_data = pData;
}
/**
*Constructs an UnsignedByte
object from a short,
*throws an exception if the parameter is out of range.
*
*@param pData >=0, <=MAX_UNSIGNED_BYTE_VALUE
*@exception RuntimeException if the parameter is out of range
*/
public UnsignedByte(short pData)
{
if((pData < 0) || (pData > MAX_UNSIGNED_BYTE_VALUE))
throw new
RuntimeException("Exception in UnsignedByte. Short value exceeds max value for an unsigned byte.");
_data = (byte)pData;
}
/**
*Constructs an UnsignedByte
object from an int,
*throws an exception if the parameter is out of range.
*
*@param pData >=0, <=MAX_UNSIGNED_BYTE_VALUE
*@exception RuntimeException if pData
is out of range
*/
public UnsignedByte(int pData)
{
if((pData < 0) || (pData > MAX_UNSIGNED_BYTE_VALUE))
throw new
RuntimeException("Exception in UnsignedByte. Int value out of range for an unsigned byte.");
_data = (byte)pData;
}
// Overrides for the abstract class Number
/**
*Returns the current value of this object as a double float,
*after conversion.
*
*@return the current value of this object as a double float
*/
public double doubleValue()
{
// if _data is negative, we know we've overflowed the high bit.
// If that's the case, return the "real" unsigned value.
double temp;
temp = (_data < 0 ? MAX_UNSIGNED_BYTE_VALUE + _data + 1 : _data);
return temp;
}
/**
*Returns a the current value of this object as a float, after conversion.
*
*@return the current value of this object as a float
*/
public float floatValue()
{
float temp;
temp = (_data < 0 ? MAX_UNSIGNED_BYTE_VALUE + _data + 1 : _data);
return temp;
}
/**
*Returns the current value of this object as an int, after conversion.
*
*@return the current value of this object as an int
*/
public int intValue()
{
int temp;
temp = (_data < 0 ? MAX_UNSIGNED_BYTE_VALUE + _data + 1 : _data);
return temp;
}
/**
*Returns the current value of this object as a long, after conversion.
*
*@return the current value of this object as a long
*/
public long longValue()
{
long temp;
temp = (_data < 0 ? MAX_UNSIGNED_BYTE_VALUE + _data + 1 : _data);
return temp;
}
// Implementation of the dis_SerializationInterface
/**
*Writes out an UnsignedByte to an output stream.
*
*@param outputstream the targetted output stream for this object
*@throws a runtime Exception if an IOException
occurs.
*
*@see SerializationInterface
*/
public void serialize(DataOutputStream pOutputStream)
{
try
{
pOutputStream.writeByte( _data);
}
catch (IOException ioError)
{
throw new
RuntimeException("Exception in UnsignedByte. Error serializing to stream.");
}
}
/**
*Reads an UnsignedByte in from DIS format.
*
*@param inputstream the input stream that builds the object.
*@exception RuntimeException if an IOException
occurs.
*
*@see SerializationInterface
*/
public void deSerialize(DataInputStream pInputStream)
{
try
{
_data = pInputStream.readByte();
}
catch(IOException ioError)
{
throw new
RuntimeException("Exception in UnsignedByte. Error deSerializing from stream.");
}
} // end of deSerialize
/**
*Returns a String object representing this UnsignedByte
value.
*
*@return a string representation of the value of this object in base 10.
*/
public String toString()
{
Integer temp = new Integer(this.intValue());
return temp.toString();
}
/**
*Of debugging interest only. You shouldn't have to use this method.
*/
public void debugTest()
{
// Some testing to make sure things work right.
UnsignedByte zero, one, two, three, four;
// test extreme values for bytes; zero, near the roll-over point, and the max value
System.out.println("Testing functionality of unsigned byte class");
zero = new UnsignedByte((byte)0);
one = new UnsignedByte((byte)127);
two = new UnsignedByte(128);
three = new UnsignedByte(129);
four = new UnsignedByte(255);
System.out.println("Values should be 0, 127, 128, 129, 255:" + zero.toString() + " " + one.toString()
+ " " + two.toString() + " " + three.toString() + " " + four.toString());
zero = new UnsignedByte((int)0);
one = new UnsignedByte((int)127);
two = new UnsignedByte((int)128);
three = new UnsignedByte((int)129);
four = new UnsignedByte((int)255);
System.out.println("Values should be 0, 127, 128, 129, 255:" + zero.toString() + " " + one.toString()
+ " " + two.toString() + " " + three.toString() + " " + four.toString());
zero = new UnsignedByte((short)0);
one = new UnsignedByte((short)127);
two = new UnsignedByte((short)128);
three = new UnsignedByte((short)129);
four = new UnsignedByte((short)255);
System.out.println("Values should be 0, 127, 128, 129, 255:" + zero.toString() + " " + one.toString()
+ " " + two.toString() + " " + three.toString() + " " + four.toString());
// Causes runtime exception
//zero = new UnsignedByte(-1);
//one = new UnsignedByte(288);
};
/**
*Makes a deep copy of the current UnsignedByte
object.
*
*@return the cloned object.
*@exception RuntimeException if cloning fails
*/
public Object clone()
{
Object newObject;
try{
newObject = super.clone(); // shallow copy
}
catch(CloneNotSupportedException cloneError)
{
throw new
RuntimeException("Exception in UnsignedByte. Error cloning object.");
}
return newObject;
}
} // end of class UnsignedByte