diff --git a/src/main/java/org/unitsofmeasurement/impl/AbstractMeasurement.java b/src/main/java/org/unitsofmeasurement/impl/AbstractMeasurement.java index 6b35bdb7..935c90c3 100644 --- a/src/main/java/org/unitsofmeasurement/impl/AbstractMeasurement.java +++ b/src/main/java/org/unitsofmeasurement/impl/AbstractMeasurement.java @@ -28,85 +28,79 @@ import javax.measure.quantity.Dimensionless; import org.unitsofmeasurement.impl.format.MeasurementFormat; -import org.unitsofmeasurement.impl.function.AbstractConverter; import org.unitsofmeasurement.impl.util.SI; /** *

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

- * - *

To avoid any lost of precision, known exact measure (e.g. physical + * + *

To avoid any lost of precision, known exact measure (e.g. physical * constants) should not be created from double constants but * from their decimal representation.
* public static final Measurement C = AbstractMeasurement.of("299792458 m/s").asType(Velocity.class); * // Speed of Light (exact). *

- * + * *

Measures can be converted to different units, the conversion precision is * determined by the specified {@link MathContext}.
* Measurement milesPerHour = C.to(MILES_PER_HOUR, MathContext.DECIMAL128); // Use BigDecimal implementation. * System.out.println(milesPerHour); - * + * * > 670616629.3843951324266284896206156 [mi_i]/h * * If no precision is specified double precision is assumed. * Measurement milesPerHour = C.to(MILES_PER_HOUR); // Use double implementation (fast). * System.out.println(milesPerHour); - * + * * > 670616629.3843951 [mi_i]/h *

- * + * *

Applications may sub-class {@link AbstractMeasurement} for particular measurements * types.
* // Measurement of type Mass based on double primitive types. - * public class MassAmount extends AbstractMeasurement { - * private final double _kilograms; // Internal SI representation. + * public class MassAmount extends AbstractMeasurement { + * private final double _kilograms; // Internal SI representation. * private Mass(double kilograms) { _kilograms = kilograms; } * public static Mass of(double value, Unit unit) { * return new Mass(unit.getConverterTo(SI.KILOGRAM).convert(value)); - * } - * public Unit getUnit() { return SI.KILOGRAM; } - * public Double getValue() { return _kilograms; } + * } + * public Unit getUnit() { return SI.KILOGRAM; } + * public Double getValue() { return _kilograms; } * ... * } - * + * * // Complex numbers measurements. * public class ComplexMeasurement extends AbstractMeasurement { * public Complex getValue() { ... } // Assuming Complex is a Number. - * ... + * ... * } - * + * * // Specializations of complex numbers measurements. - * public class Current extends ComplexMeasurement {...} + * public class Current extends ComplexMeasurement {...} * public class Tension extends ComplexMeasurement {...} *

- * + * *

All instances of this class shall be immutable.

- * + * * @author Jean-Marie Dautelle * @author Werner Keil * @version 0.3, $Date: 2014-08-03 $ */ public abstract class AbstractMeasurement> implements Measurement { -// TODO do we want to restrict Measurement to Number here? - - /** - * - */ -// private static final long serialVersionUID = -4993173119977931016L; - - private final Unit unit; - +// TODO do we want to restrict Measurement to Number here? + + protected final Unit unit; + /** * Holds a dimensionless measurement of none (exact). */ public static final AbstractMeasurement NONE = of(0, SI.ONE); - + /** * Holds a dimensionless measurement of one (exact). */ public static final AbstractMeasurement ONE = of(1, SI.ONE); - + /** * constructor. */ @@ -126,6 +120,7 @@ protected AbstractMeasurement(Unit unit) { * * @return the measurement unit. */ + @Override public Unit getUnit() { return unit; } @@ -156,6 +151,7 @@ protected AbstractMeasurement toSI() { * @throws ArithmeticException if the result is inexact and the quotient has * a non-terminating decimal expansion. */ + @Override public AbstractMeasurement to(Unit unit) { if (unit.equals(this.getUnit())) { return this; @@ -258,7 +254,7 @@ public int hashCode() { } protected abstract boolean isBig(); - + /** * Returns the String representation of this measure. The * string produced for a given measure is always the same; it is not @@ -277,10 +273,10 @@ public String toString() { protected abstract BigDecimal decimalValue(Unit unit, MathContext ctx) throws ArithmeticException; - + protected abstract double doubleValue(Unit unit) throws ArithmeticException; - + // Implements AbstractMeasurement protected final int intValue(Unit unit) throws ArithmeticException { long longValue = longValue(unit); @@ -351,7 +347,6 @@ public static AbstractMeasurement of(CharSequence csq) { throw new IllegalArgumentException(e); // TODO could we handle this differently? } } - /** * Returns the scalar measure for the specified int stated in * the specified unit. @@ -364,87 +359,6 @@ public static > AbstractMeasurement of(int intValue, Unit unit) { return new IntegerMeasurement(intValue, unit); } - - private static final class IntegerMeasurement> extends AbstractMeasurement { - - /** - * - */ - private static final long serialVersionUID = 5355395476874521709L; - - final int value; - - public IntegerMeasurement(int value, Unit unit) { - super(unit); - this.value = value; - } - - @Override - public Integer getValue() { - return value; - } - - // Implements Measurement - public double doubleValue(Unit unit) { - return (super.unit.equals(unit)) ? value : super.unit.getConverterTo(unit).convert(value); - } - - // Implements Measurement - public BigDecimal decimalValue(Unit unit, MathContext ctx) - throws ArithmeticException { - BigDecimal decimal = BigDecimal.valueOf(value); - return (super.unit.equals(unit)) ? decimal : ((AbstractConverter)super.unit.getConverterTo(unit)).convert(decimal, ctx); - } - - @Override - public long longValue(Unit unit) { - double result = doubleValue(unit); - if ((result < Long.MIN_VALUE) || (result > Long.MAX_VALUE)) { - throw new ArithmeticException("Overflow (" + result + ")"); - } - return (long) result; - } - - protected Measurement add(AbstractMeasurement that) { - return of(value + that.getValue().intValue(), getUnit()); // TODO use shift of the unit? - } - - protected Measurement subtract(AbstractMeasurement that) { - return of(value - that.getValue().intValue(), getUnit()); // TODO use shift of the unit? - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - public Measurement multiply(AbstractMeasurement that) { - return new IntegerMeasurement(value * that.getValue().intValue(), - getUnit().multiply(that.getUnit())); - } - - public Measurement multiply(Number that) { - return of(value * that.intValue(), - getUnit().multiply(that.intValue())); - } - - @SuppressWarnings({ "rawtypes", "unused", "unchecked" }) - public Measurement divide(AbstractMeasurement that) { - return new DoubleMeasurement((double)value / that.getValue().doubleValue(), getUnit().divide(that.getUnit())); - } - - @SuppressWarnings("unchecked") - public AbstractMeasurement inverse() { - return (AbstractMeasurement) of(value, getUnit().inverse()); - } - - @Override - public boolean isBig() { - return false; - } - - public Measurement divide(Number that) { - return of(value / that.intValue(), getUnit()); - } - - } - /** * Returns the scalar measure for the specified float stated in * the specified unit. @@ -458,83 +372,6 @@ public static > AbstractMeasurement of(float floatValue return new FloatMeasurement(floatValue, unit); } - private static final class FloatMeasurement> extends AbstractMeasurement { - - /** - * - */ - private static final long serialVersionUID = 7857472738562215118L; - - final float value; - - public FloatMeasurement(float value, Unit unit) { - super(unit); - this.value = value; - } - - @Override - public Float getValue() { - return value; - } - - // Implements AbstractMeasurement - public double doubleValue(Unit unit) { - return (super.unit.equals(unit)) ? value : super.unit.getConverterTo(unit).convert(value); - } - - // Implements AbstractMeasurement - protected BigDecimal decimalValue(Unit unit, MathContext ctx) - throws ArithmeticException { - BigDecimal decimal = BigDecimal.valueOf(value); // TODO check value if it is a BD, otherwise use different converter - return (super.unit.equals(unit)) ? decimal : ((AbstractConverter)super.unit.getConverterTo(unit)).convert(decimal, ctx); - } - - public long longValue(Unit unit) { - double result = doubleValue(unit); - if ((result < Long.MIN_VALUE) || (result > Long.MAX_VALUE)) { - throw new ArithmeticException("Overflow (" + result + ")"); - } - return (long) result; - } - - protected AbstractMeasurement add(AbstractMeasurement that) { - return of(value + that.getValue().floatValue(), getUnit()); // TODO use shift of the unit? - } - - protected AbstractMeasurement subtract(AbstractMeasurement that) { - return of(value - that.getValue().floatValue(), getUnit()); // TODO use shift of the unit? - } - - @SuppressWarnings("unchecked") - protected AbstractMeasurement multiply(AbstractMeasurement that) { - return (AbstractMeasurement) of(value * that.getValue().floatValue(), - getUnit().multiply(that.getUnit())); - } - - protected Measurement multiply(Number that) { - return new FloatMeasurement(value * that.floatValue(), - getUnit().multiply(that.floatValue())); - } - - @SuppressWarnings({ "unused", "rawtypes", "unchecked" }) - protected Measurement divide(AbstractMeasurement that) { - return new FloatMeasurement(value / that.getValue().floatValue(), getUnit().divide(that.getUnit())); - } - - @SuppressWarnings("unchecked") - public AbstractMeasurement inverse() { - return (AbstractMeasurement) of(value, getUnit().inverse()); - } - - public boolean isBig() { - return false; - } - - public Measurement divide(Number that) { - return of(value / that.floatValue(), getUnit()); - } - } - /** * Returns the scalar measure for the specified double stated * in the specified unit. @@ -548,77 +385,4 @@ public static > AbstractMeasurement of(double doubleVal return new DoubleMeasurement(doubleValue, unit); } - private static final class DoubleMeasurement> extends AbstractMeasurement { - - final double value; - - public DoubleMeasurement(double value, Unit unit) { - super(unit); - this.value = value; - } - - @Override - public Double getValue() { - return value; - } - - - public double doubleValue(Unit unit) { - return (super.unit.equals(unit)) ? value : super.unit.getConverterTo(unit).convert(value); - } - - @Override - public BigDecimal decimalValue(Unit unit, MathContext ctx) - throws ArithmeticException { - BigDecimal decimal = BigDecimal.valueOf(value); // TODO check value if it is a BD, otherwise use different converter - return (super.unit.equals(unit)) ? decimal : ((AbstractConverter)super.unit.getConverterTo(unit)).convert(decimal, ctx); - } - private static final long serialVersionUID = 1L; - - - @Override - public long longValue(Unit unit) { - double result = doubleValue(unit); - if ((result < Long.MIN_VALUE) || (result > Long.MAX_VALUE)) { - throw new ArithmeticException("Overflow (" + result + ")"); - } - return (long) result; - } - - protected Measurement add(AbstractMeasurement that) { - return of(value + that.getValue().doubleValue(), getUnit()); // TODO use shift of the unit? - } - - protected Measurement subtract(AbstractMeasurement that) { - return of(value - that.getValue().doubleValue(), getUnit()); // TODO use shift of the unit? - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - public Measurement multiply(AbstractMeasurement that) { - return new DoubleMeasurement(value * that.getValue().doubleValue(), getUnit().multiply(that.getUnit())); - } - - public Measurement multiply(Number that) { - return of(value * that.doubleValue(), getUnit()); - } - - @SuppressWarnings({ "rawtypes", "unchecked", "unused" }) - protected Measurement divide(AbstractMeasurement that) { - return new DoubleMeasurement(value / that.getValue().doubleValue(), getUnit().divide(that.getUnit())); - } - - public Measurement divide(Number that) { - return of(value / that.doubleValue(), getUnit()); - } - - @SuppressWarnings("unchecked") - protected AbstractMeasurement inverse() { - return (AbstractMeasurement) of(value, getUnit().inverse()); - } - - @Override - public boolean isBig() { - return false; - } - } } diff --git a/src/main/java/org/unitsofmeasurement/impl/DoubleMeasurement.java b/src/main/java/org/unitsofmeasurement/impl/DoubleMeasurement.java new file mode 100644 index 00000000..7e46ace9 --- /dev/null +++ b/src/main/java/org/unitsofmeasurement/impl/DoubleMeasurement.java @@ -0,0 +1,83 @@ +package org.unitsofmeasurement.impl; + +import java.math.BigDecimal; +import java.math.MathContext; + +import javax.measure.Measurement; +import javax.measure.Quantity; +import javax.measure.Unit; + +import org.unitsofmeasurement.impl.function.AbstractConverter; + +class DoubleMeasurement> extends AbstractMeasurement { + + final double value; + + public DoubleMeasurement(double value, Unit unit) { + super(unit); + this.value = value; + } + + @Override + public Double getValue() { + return value; + } + + + @Override + public double doubleValue(Unit unit) { + return (super.unit.equals(unit)) ? value : super.unit.getConverterTo(unit).convert(value); + } + + @Override + public BigDecimal decimalValue(Unit unit, MathContext ctx) + throws ArithmeticException { + BigDecimal decimal = BigDecimal.valueOf(value); // TODO check value if it is a BD, otherwise use different converter + return (super.unit.equals(unit)) ? decimal : ((AbstractConverter)super.unit.getConverterTo(unit)).convert(decimal, ctx); + } + + @Override + public long longValue(Unit unit) { + double result = doubleValue(unit); + if ((result < Long.MIN_VALUE) || (result > Long.MAX_VALUE)) { + throw new ArithmeticException("Overflow (" + result + ")"); + } + return (long) result; + } + + protected Measurement add(AbstractMeasurement that) { + return of(value + that.getValue().doubleValue(), getUnit()); // TODO use shift of the unit? + } + + protected Measurement subtract(AbstractMeasurement that) { + return of(value - that.getValue().doubleValue(), getUnit()); // TODO use shift of the unit? + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public Measurement multiply(AbstractMeasurement that) { + return new DoubleMeasurement(value * that.getValue().doubleValue(), getUnit().multiply(that.getUnit())); + } + + public Measurement multiply(Number that) { + return of(value * that.doubleValue(), getUnit()); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + protected Measurement divide(AbstractMeasurement that) { + return new DoubleMeasurement(value / that.getValue().doubleValue(), getUnit().divide(that.getUnit())); + } + + public Measurement divide(Number that) { + return of(value / that.doubleValue(), getUnit()); + } + + @SuppressWarnings("unchecked") + protected AbstractMeasurement inverse() { + return (AbstractMeasurement) of(value, getUnit().inverse()); + } + + @Override + public boolean isBig() { + return false; + } +} \ No newline at end of file diff --git a/src/main/java/org/unitsofmeasurement/impl/FloatMeasurement.java b/src/main/java/org/unitsofmeasurement/impl/FloatMeasurement.java new file mode 100644 index 00000000..a92bab9b --- /dev/null +++ b/src/main/java/org/unitsofmeasurement/impl/FloatMeasurement.java @@ -0,0 +1,87 @@ +package org.unitsofmeasurement.impl; + +import java.math.BigDecimal; +import java.math.MathContext; + +import javax.measure.Measurement; +import javax.measure.Quantity; +import javax.measure.Unit; + +import org.unitsofmeasurement.impl.function.AbstractConverter; + +class FloatMeasurement> extends AbstractMeasurement { + + + final float value; + + public FloatMeasurement(float value, Unit unit) { + super(unit); + this.value = value; + } + + @Override + public Float getValue() { + return value; + } + + // Implements AbstractMeasurement + @Override + public double doubleValue(Unit unit) { + return (super.unit.equals(unit)) ? value : super.unit.getConverterTo(unit).convert(value); + } + + // Implements AbstractMeasurement + @Override + protected BigDecimal decimalValue(Unit unit, MathContext ctx) + throws ArithmeticException { + BigDecimal decimal = BigDecimal.valueOf(value); // TODO check value if it is a BD, otherwise use different converter + return (super.unit.equals(unit)) ? decimal : ((AbstractConverter)super.unit.getConverterTo(unit)).convert(decimal, ctx); + } + + @Override + public long longValue(Unit unit) { + double result = doubleValue(unit); + if ((result < Long.MIN_VALUE) || (result > Long.MAX_VALUE)) { + throw new ArithmeticException("Overflow (" + result + ")"); + } + return (long) result; + } + + protected AbstractMeasurement add(AbstractMeasurement that) { + return of(value + that.getValue().floatValue(), getUnit()); // TODO use shift of the unit? + } + + protected AbstractMeasurement subtract(AbstractMeasurement that) { + return of(value - that.getValue().floatValue(), getUnit()); // TODO use shift of the unit? + } + + @SuppressWarnings("unchecked") + protected AbstractMeasurement multiply(AbstractMeasurement that) { + return (AbstractMeasurement) of(value * that.getValue().floatValue(), + getUnit().multiply(that.getUnit())); + } + + protected Measurement multiply(Number that) { + return new FloatMeasurement(value * that.floatValue(), + getUnit().multiply(that.floatValue())); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + protected Measurement divide(AbstractMeasurement that) { + return new FloatMeasurement(value / that.getValue().floatValue(), getUnit().divide(that.getUnit())); + } + + @SuppressWarnings("unchecked") + public AbstractMeasurement inverse() { + return (AbstractMeasurement) of(value, getUnit().inverse()); + } + + @Override + public boolean isBig() { + return false; + } + + public Measurement divide(Number that) { + return of(value / that.floatValue(), getUnit()); + } +} \ No newline at end of file diff --git a/src/main/java/org/unitsofmeasurement/impl/IntegerMeasurement.java b/src/main/java/org/unitsofmeasurement/impl/IntegerMeasurement.java new file mode 100644 index 00000000..235d0998 --- /dev/null +++ b/src/main/java/org/unitsofmeasurement/impl/IntegerMeasurement.java @@ -0,0 +1,88 @@ +package org.unitsofmeasurement.impl; + +import java.math.BigDecimal; +import java.math.MathContext; + +import javax.measure.Measurement; +import javax.measure.Quantity; +import javax.measure.Unit; + +import org.unitsofmeasurement.impl.function.AbstractConverter; + +class IntegerMeasurement> extends AbstractMeasurement { + + + final int value; + + public IntegerMeasurement(int value, Unit unit) { + super(unit); + this.value = value; + } + + @Override + public Integer getValue() { + return value; + } + + // Implements Measurement + @Override + public double doubleValue(Unit unit) { + return (super.unit.equals(unit)) ? value : super.unit.getConverterTo(unit).convert(value); + } + + // Implements Measurement + @Override + public BigDecimal decimalValue(Unit unit, MathContext ctx) + throws ArithmeticException { + BigDecimal decimal = BigDecimal.valueOf(value); + return (super.unit.equals(unit)) ? decimal : ((AbstractConverter)super.unit.getConverterTo(unit)).convert(decimal, ctx); + } + + @Override + public long longValue(Unit unit) { + double result = doubleValue(unit); + if ((result < Long.MIN_VALUE) || (result > Long.MAX_VALUE)) { + throw new ArithmeticException("Overflow (" + result + ")"); + } + return (long) result; + } + + protected Measurement add(AbstractMeasurement that) { + return of(value + that.getValue().intValue(), getUnit()); // TODO use shift of the unit? + } + + protected Measurement subtract(AbstractMeasurement that) { + return of(value - that.getValue().intValue(), getUnit()); // TODO use shift of the unit? + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public Measurement multiply(AbstractMeasurement that) { + return new IntegerMeasurement(value * that.getValue().intValue(), + getUnit().multiply(that.getUnit())); + } + + public Measurement multiply(Number that) { + return of(value * that.intValue(), + getUnit().multiply(that.intValue())); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public Measurement divide(AbstractMeasurement that) { + return new DoubleMeasurement(value / that.getValue().doubleValue(), getUnit().divide(that.getUnit())); + } + + @SuppressWarnings("unchecked") + public AbstractMeasurement inverse() { + return (AbstractMeasurement) of(value, getUnit().inverse()); + } + + @Override + public boolean isBig() { + return false; + } + + public Measurement divide(Number that) { + return of(value / that.intValue(), getUnit()); + } + +} \ No newline at end of file