/* * @(#)XDouble.java 2.5.0 6 September 2006 * * Copyright 2006 * College of Computer and Information Science * Northeastern University * Boston, MA 02115 * * The Java Power Tools software may be used for educational * purposes as long as this copyright notice is retained intact * at the top of all source files. * * To discuss possible commercial use of this software, * contact Richard Rasala at Northeastern University, * College of Computer and Information Science, * 617-373-2462 or rasala@ccs.neu.edu. * * The Java Power Tools software has been designed and built * in collaboration with Viera Proulx and Jeff Raab. * * Should this software be modified, the words "Modified from * Original" must be included as a comment below this notice. * * All publication rights are retained. This software or its * documentation may not be published in any media either * in whole or in part without explicit permission. * * This software was created with support from Northeastern * University and from NSF grant DUE-9950829. */ package edu.neu.ccs; import edu.neu.ccs.parser.*; import java.beans.*; import java.text.ParseException; /** *
Object wrapper for the primitive
* double type that also provides
* {@link Stringable Stringable} capabilities.
The default value for this class is
* the double representation of zero.
As of 2.5.0, added methods isInfinite and
* isNaN in imitation of class Double,
* and also added methods isFinite to make the test
* for finiteness directly available to a caller.
double value.
*
* @see #XDouble(double)
* @see #XDouble(String)
*/
public XDouble() {}
/**
* Constructs a wrapper for the given
* double value.
*
* @param d the value to be wrapped
* @see #XDouble()
* @see #XDouble(String)
*/
public XDouble(double d) {
value = d;
}
/**
* Constructs a wrapper for the double value
* whose state information is encapsulated
* in the given String data.
*
* @param s a String representation
* of the desired value
* @throws ParseException if the data is malformed
* @see #XDouble()
* @see #XDouble(double)
*/
public XDouble(String s) throws ParseException {
fromStringData(s);
}
////////////////
// Stringable //
////////////////
public void fromStringData(String data) throws ParseException {
double oldValue = value;
Parser p = ParserUtilities.getDefaultParser();
Object obj = p.parse(data);
// store extracted value
if (obj instanceof XNumber) {
XNumber n = (XNumber)obj;
value = n.doubleValue();
}
// otherwise throw an exception
else {
throw new ParseException(
"Expected numeric value.", data.length());
}
// report property change
changeAdapter.firePropertyChange(
VALUE,
new Double(oldValue),
data);
}
public String toStringData() {
return value + "";
}
/////////////
// XNumber //
/////////////
public byte byteValue() {
if ((getValue() > Byte.MAX_VALUE) ||
(getValue() < Byte.MIN_VALUE))
{
throw new NumberFormatException(
"Number beyond precision of a byte.");
}
return (byte)getValue();
}
public short shortValue() {
if ((getValue() > Short.MAX_VALUE) ||
(getValue() < Short.MIN_VALUE))
{
throw new NumberFormatException(
"Number beyond precision of a short.");
}
return (short)getValue();
}
public int intValue() {
if ((getValue() > Integer.MAX_VALUE) ||
(getValue() < Integer.MIN_VALUE))
{
throw new NumberFormatException(
"Number beyond precision of an int.");
}
return (int)getValue();
}
public long longValue() {
if ((getValue() > Long.MAX_VALUE) ||
(getValue() < Long.MIN_VALUE))
{
throw new NumberFormatException(
"Number beyond precision of a long.");
}
return (long)getValue();
}
public float floatValue() {
if ((getValue() > Float.MAX_VALUE) ||
(getValue() < -Float.MAX_VALUE))
{
throw new NumberFormatException(
"Number beyond precision of a float.");
}
return (float)getValue();
}
public double doubleValue() {
return getValue();
}
////////////////
// Public API //
////////////////
/**
* Returns true if the wrapped object
* is equal to the given object, and false
* if it is not.
*
* @param other the object to be compared with the wrapped object
*/
public boolean equals(Object other) {
if (other instanceof XByte)
return getValue() == ((XDouble)other).getValue();
return false;
}
/**
* Returns an int hash code
* appropriate for the wrapped object.
*/
public int hashCode() {
return (new Double(getValue())).hashCode();
}
/**
* Returns a String representation
* of the wrapped value.
*/
public String toString() {
return value + "";
}
/**
* Sets the value wrapped by this object
* to the given value.
*
* @param d the value to be wrapped
* @see #getValue()
*/
public void setValue(double d) {
double oldValue = value;
value = d;
// if the value has changed
if (getValue() != oldValue) {
// notify listeners of property change
changeAdapter.firePropertyChange(
VALUE,
new Double(oldValue),
new Double(getValue()));
}
}
/**
* Returns the value wrapped by this object.
*
* @see #setValue(double)
*/
public double getValue() {
return value;
}
/**
* Returns true if this XDouble is finite, that is,
* it is not positive or negative infinity nor
* is it NaN.
*/
public boolean isFinite() {
return (! (isInfinite(value) || isNaN(value)));
}
/**
* Returns true if this XDouble is either * positive or negative infinity.
*/ public boolean isInfinite() { return Double.isInfinite(value); } /** *Returns true if this XDouble is NaN, * that is, "not a number".
*/ public boolean isNaN() { return Double.isNaN(value); } //////////////////// // Static methods // //////////////////// /** * Returns true if the given double is finite, that is, * it is not positive or negative infinity nor * is it NaN. */ public static boolean isFinite(double v) { return (! (isInfinite(v) || isNaN(v))); } /** *Returns true if the given double is either * positive or negative infinity.
* *Identical to Double.isInfinite.
Returns true if the given double is NaN, * that is, "not a number".
* *Identical to Double.isNaN.
double value from a String
* using the current shared parser.
*
* @param s the String data to parse
* @return the extracted double value
* @throws NumberFormatException if the data is malformed
*/
public static double parseDouble(String s)
throws NumberFormatException
{
try {
return (new XDouble(s)).value;
}
catch (ParseException e) {
throw new NumberFormatException(
formatErrorMessage(e, s));
}
}
/**
* Returns an array of primitive double values
* copied from the given array
* of XDouble objects.
*
* @param x an array of XDoubles
* @return the resulting array
* of double values
* @see #toXArray(double[])
*/
public static double[] toPrimitiveArray(XDouble[] x) {
// return null array if appropriate
if (x == null)
return null;
// otherwise perform the type translation
double[] temp = new double[x.length];
for (int i = 0; i < temp.length; i++)
if (x[i] != null)
temp[i] = x[i].getValue();
return temp;
}
/**
* Returns an array of XDouble objects
* initialized from the given array
* of double values.
*
* @param a an array of doubles
* @return the resulting array
* of XDouble objects
* @see #toPrimitiveArray(XDouble[])
*/
public static XDouble[] toXArray(double[] a) {
// return null array if appropriate
if (a == null)
return null;
// otherwise perform the type translation
XDouble[] temp = new XDouble[a.length];
for (int i = 0; i < temp.length; i++)
temp[i] = new XDouble(a[i]);
return temp;
}
}