001/*
002 * Units of Measurement Reference Implementation
003 * Copyright (c) 2005-2016, Jean-Marie Dautelle, Werner Keil, V2COM.
004 *
005 * All rights reserved.
006 *
007 * Redistribution and use in source and binary forms, with or without modification,
008 * are permitted provided that the following conditions are met:
009 *
010 * 1. Redistributions of source code must retain the above copyright notice,
011 *    this list of conditions and the following disclaimer.
012 *
013 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
014 *    and the following disclaimer in the documentation and/or other materials provided with the distribution.
015 *
016 * 3. Neither the name of JSR-363 nor the names of its contributors may be used to endorse or promote products
017 *    derived from this software without specific prior written permission.
018 *
019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
021 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
022 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
023 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
026 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
028 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029 */
030package tec.units.ri.quantity;
031
032import javax.measure.Quantity;
033import javax.measure.Unit;
034import javax.measure.UnconvertibleException;
035import javax.measure.UnitConverter;
036
037import tec.units.ri.AbstractQuantity;
038import tec.units.ri.format.QuantityFormat;
039
040/**
041 * An amount of quantity, consisting of a Number and a Unit. NumberQuantity objects are immutable.
042 * 
043 * @see AbstractQuantity
044 * @see Quantity
045 * @author <a href="mailto:werner@uom.technology">Werner Keil</a>
046 * @param <Q>
047 *          The type of the quantity.
048 * @version 0.13, $Date: 2016-06-21 $
049 */
050public class NumberQuantity<Q extends Quantity<Q>> extends AbstractQuantity<Q> {
051
052  /**
053   * 
054   */
055  // private static final long serialVersionUID = 7312161895652321241L;
056
057  private final Number value;
058
059  /*
060   * (non-Javadoc)
061   * 
062   * @see AbstractQuantity#equals(java.lang.Object)
063   */
064  @Override
065  public boolean equals(Object obj) {
066    if (obj == null)
067      return false;
068    if (obj == this)
069      return true;
070    if (this.getClass() == obj.getClass()) {
071      return super.equals(obj);
072    } else {
073      if (obj instanceof Quantity) {
074        @SuppressWarnings("rawtypes")
075        Quantity m = (Quantity) obj;
076        if (m.getValue().getClass() == this.getValue().getClass() && m.getUnit().getClass() == this.getUnit().getClass()) {
077          return super.equals(obj);
078        } else {
079          // if (this.getQuantityUnit() instanceof AbstractUnit<?>) {
080          // if
081          // }
082          return super.equals(obj);
083        }
084      }
085      return false;
086    }
087  }
088
089  /**
090   * Indicates if this quantity is exact.
091   */
092  private final boolean isExact;
093
094  /**
095   * Holds the exact value (when exact) stated in this quantity's unit.
096   */
097  // private long exactValue;
098
099  /**
100   * Holds the minimum value stated in this quantity's unit. For inexact measures: minimum < maximum
101   */
102  // private double minimum;
103
104  /**
105   * Holds the maximum value stated in this quantity's unit. For inexact measures: maximum > minimum
106   */
107  // private double maximum;
108
109  public NumberQuantity(Number number, Unit<Q> unit) {
110    super(unit);
111    value = number;
112    isExact = false;
113  }
114
115  /*
116   * (non-Javadoc)
117   * 
118   * @see AbstractQuantity#doubleValue(javax.measure.Unit)
119   */
120  @Override
121  public double doubleValue(Unit<Q> unit) {
122    Unit<Q> myUnit = getUnit();
123    try {
124      UnitConverter converter = unit.getConverterTo(myUnit);
125      return converter.convert(getValue().doubleValue());
126    } catch (UnconvertibleException e) {
127      throw e;
128    }
129  }
130
131  protected final int intValue(Unit<Q> unit) throws ArithmeticException {
132    long longValue = longValue(unit);
133    if ((longValue < Integer.MIN_VALUE) || (longValue > Integer.MAX_VALUE)) {
134      throw new ArithmeticException("Cannot convert " + longValue + " to int (overflow)");
135    }
136    return (int) longValue;
137  }
138
139  /*
140   * (non-Javadoc)
141   * 
142   * @see javax.measure.Quantity#getValue()
143   */
144  public Number getValue() {
145    return value;
146  }
147
148  /**
149   * Indicates if this measured quantity is exact. An exact quantity is guaranteed exact only when stated in this quantity's unit (e.g.
150   * <code>this.longValue()</code>); stating the quantity in any other unit may introduce conversion errors.
151   * 
152   * @return <code>true</code> if this quantity is exact; <code>false</code> otherwise.
153   */
154  public boolean isExact() {
155    return isExact;
156  }
157
158  @SuppressWarnings({ "rawtypes", "unchecked" })
159  protected Quantity<Q> add(AbstractQuantity<Q> that) {
160    final Quantity<Q> thatToUnit = that.to(getUnit());
161    return new NumberQuantity(this.getValue().doubleValue() + thatToUnit.getValue().doubleValue(), getUnit());
162  }
163
164  public String toString() {
165    return String.valueOf(getValue()) + " " + String.valueOf(getUnit());
166  }
167
168  @SuppressWarnings({ "rawtypes", "unchecked" })
169  public Quantity<?> multiply(Quantity<?> that) {
170    final Unit<?> unit = getUnit().multiply(that.getUnit());
171    return new NumberQuantity((getValue().doubleValue() * that.getValue().doubleValue()), unit);
172  }
173
174  public Quantity<Q> multiply(Number that) {
175    return (NumberQuantity<Q>) NumberQuantity.of((getValue().doubleValue() * that.doubleValue()), getUnit());
176  }
177
178  @SuppressWarnings({ "rawtypes", "unchecked" })
179  public Quantity<Q> divide(Quantity<?> that) {
180    final Unit<?> unit = getUnit().divide(that.getUnit());
181    return new NumberQuantity((getValue().doubleValue() / that.getValue().doubleValue()), unit);
182  }
183
184  public Quantity<Q> divide(Number that) {
185    return NumberQuantity.of(getValue().doubleValue() / that.doubleValue(), getUnit());
186  }
187
188  public Quantity<Q> inverse() {
189    @SuppressWarnings({ "rawtypes", "unchecked" })
190    final Quantity<Q> m = new NumberQuantity(1d / getValue().doubleValue(), getUnit().inverse());
191    return m;
192  }
193
194  @SuppressWarnings({ "rawtypes", "unchecked" })
195  public Quantity<Q> subtract(Quantity<Q> that) {
196    final Quantity<Q> thatToUnit = (Quantity<Q>) that.to(getUnit());
197    return new NumberQuantity(this.getValue().doubleValue() - thatToUnit.getValue().doubleValue(), getUnit());
198  }
199
200  @SuppressWarnings({ "rawtypes", "unchecked" })
201  public Quantity<Q> add(Quantity<Q> that) {
202    final Quantity<Q> thatToUnit = (Quantity<Q>) that.to(getUnit());
203    return new NumberQuantity(this.getValue().doubleValue() + thatToUnit.getValue().doubleValue(), getUnit());
204  }
205
206  /**
207   * Returns the scalar quantity for the specified <code>long</code> stated in the specified unit.
208   *
209   * @param longValue
210   *          the quantity value.
211   * @param unit
212   *          the measurement unit.
213   * @return the corresponding <code>int</code> quantity.
214   */
215  public static <Q extends Quantity<Q>> AbstractQuantity<Q> of(long longValue, Unit<Q> unit) {
216    return new LongQuantity<Q>(longValue, unit);
217  }
218
219  /**
220   * Returns the scalar quantity for the specified <code>int</code> stated in the specified unit.
221   *
222   * @param intValue
223   *          the quantity value.
224   * @param unit
225   *          the measurement unit.
226   * @return the corresponding <code>int</code> quantity.
227   */
228  public static <Q extends Quantity<Q>> AbstractQuantity<Q> of(int intValue, Unit<Q> unit) {
229    return new IntegerQuantity<Q>(intValue, unit);
230  }
231
232  /**
233   * Returns the scalar quantity for the specified <code>short</code> stated in the specified unit.
234   *
235   * @param value
236   *          the quantity value.
237   * @param unit
238   *          the measurement unit.
239   * @return the corresponding <code>short</code> quantity.
240   */
241  public static <Q extends Quantity<Q>> AbstractQuantity<Q> of(short value, Unit<Q> unit) {
242    return new ShortQuantity<Q>(value, unit);
243  }
244
245  /**
246   * Returns the scalar quantity for the specified <code>float</code> stated in the specified unit.
247   *
248   * @param floatValue
249   *          the measurement value.
250   * @param unit
251   *          the measurement unit.
252   * @return the corresponding <code>float</code> quantity.
253   */
254  public static <Q extends Quantity<Q>> AbstractQuantity<Q> of(float floatValue, Unit<Q> unit) {
255    return new FloatQuantity<Q>(floatValue, unit);
256  }
257
258  /**
259   * Returns the scalar quantity for the specified <code>double</code> stated in the specified unit.
260   *
261   * @param doubleValue
262   *          the measurement value.
263   * @param unit
264   *          the measurement unit.
265   * @return the corresponding <code>double</code> quantity.
266   */
267  public static <Q extends Quantity<Q>> AbstractQuantity<Q> of(double doubleValue, Unit<Q> unit) {
268    return new DoubleQuantity<Q>(doubleValue, unit);
269  }
270
271  /**
272   * Returns the decimal quantity of unknown type corresponding to the specified representation. This method can be used to parse dimensionless
273   * quantities.<br/>
274   * <code>
275   *     Quatity<Dimensionless> proportion = AbstractQuantity.of("0.234").asType(Dimensionless.class);
276   * </code>
277   *
278   * <p>
279   * Note: This method handles only {@link tec.units.ri.SimpleUnitFormat.UnitFormat#getStandard standard} unit format (<a
280   * href="http://unitsofmeasure.org/">UCUM</a> based). Locale-sensitive quantity formatting and parsing are handled by the {@link MeasurementFormat}
281   * class and its subclasses.
282   * </p>
283   *
284   * @param csq
285   *          the decimal value and its unit (if any) separated by space(s).
286   * @return <code>QuantityFormat.getInstance().parse(csq)</code>
287   */
288  public static Quantity<?> parse(CharSequence csq) {
289    return QuantityFormat.getInstance().parse(csq);
290  }
291}