/*
 * JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
 * Copyright (C) 2007 - JScience (http://jscience.org/)
 * All rights reserved.
 * 
 * Permission to use, copy, modify, and distribute this software is
 * freely granted, provided that this notice is preserved.
 */
package javax.measure;

import java.io.Serializable;
import java.math.BigDecimal;
import java.math.MathContext;

import javax.measure.quantity.Quantity;
import javax.measure.unit.CompoundUnit;
import javax.measure.unit.Unit;

/**
 * 

This class represents the result of a measurement stated in a * known unit.

* *

There is no constraint upon the measurement value itself: scalars, * vectors, or even data sets are valid values as long as * an aggregate magnitude can be determined (see {@link Measurable}).

* * @author Jean-Marie Dautelle * @version 4.2, August 26, 2007 */ public abstract class Measure implements Measurable, Serializable { /** * Default constructor. */ protected Measure() { } /** * Returns the scalar measure for the specified double * stated in the specified unit. * * @param doubleValue the measurement value. * @param unit the measurement unit. */ public static Measure valueOf( double doubleValue, Unit unit) { return new Double(doubleValue, unit); } /** * Returns the scalar measure for the specified double * stated in the specified unit. * * @param longValue the measurement value. * @param unit the measurement unit. */ public static Measure valueOf( long longValue, Unit unit) { return new Long(longValue, unit); } /** * Returns the scalar measure for the specified float * stated in the specified unit. * * @param floatValue the measurement value. * @param unit the measurement unit. */ public static Measure valueOf( float floatValue, Unit unit) { return new Float(floatValue, unit); } /** * Returns the scalar measure for the specified int * stated in the specified unit. * * @param intValue the measurement value. * @param unit the measurement unit. */ public static Measure valueOf( int intValue, Unit unit) { return new Integer(intValue, unit); } /** * Returns the measurement value of this measure. * * @return the measurement value. */ public abstract V getValue(); /** * Returns the measurement unit of this measure. * * @return the measurement unit. */ public abstract Unit getUnit(); /** * Returns the measure equivalent to this measure but stated in the * specified unit. This method may result in lost of precision * (e.g. measure of integral value). * * @param unit the new measurement unit. * @return the measure stated in the specified unit. */ public abstract Measure to(Unit unit); /** * Returns the value of this measure stated in the specified unit as * a double. If the measure has too great a magnitude to * be represented as a double, it will be converted to * Double.NEGATIVE_INFINITY or * Double.POSITIVE_INFINITY as appropriate. * * @param unit the unit in which this measure is stated. * @return the numeric value after conversion to type double. */ public abstract double doubleValue(Unit unit); /** * Returns the estimated integral value of this measure stated in * the specified unit as a long. * *

Note: This method differs from the Number.longValue() * in the sense that the closest integer value is returned * and an ArithmeticException is raised instead * of a bit truncation in case of overflow (safety critical).

* * @param unit the unit in which the measurable value is stated. * @return the numeric value after conversion to type long. * @throws ArithmeticException if this quantity cannot be represented * as a long number in the specified unit. */ public long longValue(Unit unit) throws ArithmeticException { double doubleValue = doubleValue(unit); if (java.lang.Double.isNaN(doubleValue) || (doubleValue < java.lang.Long.MIN_VALUE) || (doubleValue > java.lang.Long.MAX_VALUE)) throw new ArithmeticException(doubleValue + " " + unit + " cannot be represented as long"); return Math.round(doubleValue); } /** * Returns the value of this measure stated in the specified unit as a * float. If the measure has too great a magnitude to be * represented as a float, it will be converted to * Float.NEGATIVE_INFINITY or * Float.POSITIVE_INFINITY as appropriate. * * @param unit the unit in which the measure is stated. * @return the numeric value after conversion to type float. */ public float floatValue(Unit unit) { return (float) doubleValue(unit); } /** * Returns the estimated integral value of this measure stated in * the specified unit as a int. * *

Note: This method differs from the Number.intValue() * in the sense that the closest integer value is returned * and an ArithmeticException is raised instead * of a bit truncation in case of overflow (safety critical).

* * @param unit the unit in which the measurable value is stated. * @return the numeric value after conversion to type int. * @throws ArithmeticException if this quantity cannot be represented * as a int number in the specified unit. */ public int intValue(Unit unit) { long longValue = longValue(unit); if ((longValue > java.lang.Integer.MAX_VALUE) || (longValue < java.lang.Integer.MIN_VALUE)) throw new ArithmeticException("Overflow"); return (int) longValue; } /** * Compares this measure against the specified object for * strict equality (same unit and amount). * To compare measures stated using different units the * {@link #compareTo} method should be used. * * @param obj the object to compare with. * @return true if both objects are identical (same * unit and same amount); false otherwise. */ @SuppressWarnings("unchecked") public boolean equals(Object obj) { if (!(obj instanceof Measure)) return false; Measure that = (Measure) obj; return this.getUnit().equals(that.getUnit()) && this.getValue().equals(that.getValue()); } /** * Returns the hash code for this scalar. * * @return the hash code value. */ public int hashCode() { return getUnit().hashCode() + getValue().hashCode(); } /** * Returns the String representation of this measure * The string produced for a given measure is always the same; * it is not affected by locale. This means that it can be used * as a canonical string representation for exchanging data, * or as a key for a Hashtable, etc. Locale-sensitive * measure formatting and parsing is handled by the {@link * MeasureFormat} class and its subclasses. * * @return the string representation of this measure. */ public String toString() { if (getUnit() instanceof CompoundUnit) return MeasureFormat.DEFAULT.formatCompound(doubleValue(getUnit()), getUnit(), new StringBuffer(), null).toString(); return getValue() + " " + getUnit(); } /** * Compares this measure to the specified measurable quantity. * This method compares the {@link Measurable#doubleValue(Unit)} of * both this measure and the specified measurable stated in the * same unit (this measure's {@link #getUnit() unit}). * * @return a negative integer, zero, or a positive integer as this measure * is less than, equal to, or greater than the specified measurable * quantity. * @return Double.compare(this.doubleValue(getUnit()), * that.doubleValue(getUnit())) */ public int compareTo(Measurable that) { return java.lang.Double.compare(doubleValue(getUnit()), that .doubleValue(getUnit())); } /** * Holds scalar implementation for double values. */ private static final class Double extends Measure { private final double _value; private final Unit _unit; public Double(double value, Unit unit) { _value = value; _unit = unit; } @Override public Unit getUnit() { return _unit; } @Override public java.lang.Double getValue() { return _value; } @Override public Measure to(Unit unit) { if ((unit == _unit) || (unit.equals(_unit))) return this; return new Double(doubleValue(unit), unit); } public double doubleValue(Unit unit) { if ((unit == _unit) || (unit.equals(_unit))) return _value; return _unit.getConverterTo(unit).convert(_value); } private static final long serialVersionUID = 1L; } /** * Holds scalar implementation for long values. */ private static final class Long extends Measure { private final long _value; private final Unit _unit; public Long(long value, Unit unit) { _value = value; _unit = unit; } @Override public Unit getUnit() { return _unit; } @Override public java.lang.Long getValue() { return _value; } @Override public Measure to(Unit unit) { if ((unit == _unit) || (unit.equals(_unit))) return this; return new Long(longValue(unit), unit); } public double doubleValue(Unit unit) { if ((unit == _unit) || (unit.equals(_unit))) return _value; return _unit.getConverterTo(unit).convert(_value); } public long longValue(Unit unit) throws ArithmeticException { if ((unit == _unit) || (unit.equals(_unit))) return _value; // No conversion, returns value directly. return super.longValue(unit); } private static final long serialVersionUID = 1L; } /** * Holds scalar implementation for float values. */ private static final class Float extends Measure { private final float _value; private final Unit _unit; public Float(float value, Unit unit) { _value = value; _unit = unit; } @Override public Unit getUnit() { return _unit; } @Override public java.lang.Float getValue() { return _value; } @Override public Measure to(Unit unit) { if ((unit == _unit) || (unit.equals(_unit))) return this; return new Float(floatValue(unit), unit); } public double doubleValue(Unit unit) { if ((unit == _unit) || (unit.equals(_unit))) return _value; return _unit.getConverterTo(unit).convert(_value); } private static final long serialVersionUID = 1L; } /** * Holds scalar implementation for long values. */ private static final class Integer extends Measure { private final int _value; private final Unit _unit; public Integer(int value, Unit unit) { _value = value; _unit = unit; } @Override public Unit getUnit() { return _unit; } @Override public java.lang.Integer getValue() { return _value; } @Override public Measure to(Unit unit) { if ((unit == _unit) || (unit.equals(_unit))) return this; return new Integer(intValue(unit), unit); } public double doubleValue(Unit unit) { if ((unit == _unit) || (unit.equals(_unit))) return _value; return _unit.getConverterTo(unit).convert(_value); } public long longValue(Unit unit) throws ArithmeticException { if ((unit == _unit) || (unit.equals(_unit))) return _value; // No conversion, returns value directly. return super.longValue(unit); } private static final long serialVersionUID = 1L; } /** * @deprecated {@link DecimalMeasure} should be used directly. */ public static Measure valueOf( BigDecimal decimal, Unit unit) { return DecimalMeasure.valueOf(decimal, unit); } /** * @deprecated {@link DecimalMeasure} should be used directly and * MathContext specified explicitly when * {@link DecimalMeasure#to(Unit, MathContext) converting}. */ public static Measure valueOf( BigDecimal decimal, Unit unit, MathContext mathContext) { return DecimalMeasure.valueOf(decimal, unit); } /** * @deprecated {@link VectorMeasure} should be used directly. */ public static Measure valueOf( double[] components, Unit unit) { return VectorMeasure.valueOf(components, unit); } }

Ads help maintain this website.