001/* 002 * Units of Measurement API 003 * Copyright (c) 2014-2023, Jean-Marie Dautelle, Werner Keil, Otavio Santana. 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-385 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 javax.measure.test.quantity; 031 032import javax.measure.Quantity; 033import javax.measure.Unit; 034import javax.measure.quantity.Dimensionless; 035import javax.measure.test.TestUnit; 036import javax.measure.test.unit.BaseUnit; 037 038/** 039 * @author Werner Keil 040 * @version 2.0 041 * @since 1.0 042 */ 043public abstract class TestQuantity<Q extends Quantity<Q>> implements Quantity<Q>, Comparable<Quantity<Q>> { 044 045 @SuppressWarnings("rawtypes") 046 public static final Quantity<Dimensionless> ONE = new DimensionlessQuantity(1d, (BaseUnit) TestUnit.ONE); 047 048 protected double scalar; // value in reference value 049 protected double value; // value in value (Unit unit) 050 protected TestUnit<Q> unit; // unit 051 private final Class<Q> type; // quantity type 052 private final Scale scale; 053 054 protected TestQuantity(Class<Q> type, Scale scale) { 055 this.type = type; 056 this.scale = scale; 057 } 058 059 protected TestQuantity(Class<Q> type) { 060 this(type, Scale.ABSOLUTE); 061 } 062 063 public Class<Q> getType() { 064 return this.type; 065 } 066 067 public TestQuantity<Q> add(TestQuantity<Q> dn, TestQuantity<Q> d1, TestQuantity<Q> d2, TestUnit<Q> au) { 068 if (d1.unit == d2.unit) { 069 dn.unit = d1.unit; 070 dn.scalar = d1.scalar + d2.scalar; 071 dn.value = d1.value + d2.value; 072 } else { 073 dn.unit = au; 074 dn.scalar = d1.scalar + d2.scalar; 075 dn.value = dn.scalar; 076 } 077 return dn; 078 } 079 080 public TestQuantity<Q> subtract(TestQuantity<Q> dn, TestQuantity<Q> d1, TestQuantity<Q> d2, TestUnit<Q> au) { 081 if (d1.unit == d2.unit) { 082 dn.unit = d1.unit; 083 dn.scalar = d1.scalar - d2.scalar; 084 dn.value = d1.value - d2.value; 085 } else { 086 dn.unit = au; 087 dn.scalar = d1.scalar - d2.scalar; 088 dn.value = dn.scalar; 089 } 090 return dn; 091 } 092 093 public boolean eq(TestQuantity<Q> d1) { 094 return (scalar == d1.scalar); 095 } 096 097 public boolean ne(TestQuantity<Q> d1) { 098 return (scalar != d1.scalar); 099 } 100 101 public boolean gt(TestQuantity<Q> d1) { 102 return (scalar > d1.scalar); 103 } 104 105 public boolean lt(TestQuantity<Q> d1) { 106 return (scalar < d1.scalar); 107 } 108 109 public boolean ge(TestQuantity<Q> d1) { 110 return (scalar >= d1.scalar); 111 } 112 113 public boolean le(TestQuantity<Q> d1) { 114 return (scalar <= d1.scalar); 115 } 116 117 @Override 118 public String toString() { 119 return (Double.valueOf(value)).toString() + ' ' + String.valueOf(unit); 120 } 121 122 /** 123 * Compares this quantity to the specified Measurement quantity. The default implementation compares the {@link Quantity#getValue()} of both this 124 * quantity and the specified Quantity stated in the same unit (this quantity's {@link #getUnit() unit}). 125 * 126 * @return a negative integer, zero, or a positive integer as this quantity is less than, equal to, or greater than the specified Quantity 127 * quantity. 128 */ 129 public int compareTo(Quantity<Q> that) { 130 return Double.compare(value, that.getValue().doubleValue()); 131 } 132 133 protected String showInUnits(TestUnit<?> u, int precision) { 134 double result = scalar / u.getMultFactor(); 135 136 String str = (Double.valueOf(result)).toString(); 137 char cs[] = str.toCharArray(); 138 int i = 0; 139 while (i < cs.length && (cs[i] >= '0' && cs[i] <= '9' || cs[i] == '.')) { 140 i++; 141 } 142 Double bd = new Double(new String(cs, 0, i)); 143 // BigDecimal bd2 = bd.setScale(precision, RoundingMode.HALF_UP); 144 // str = bd2.toString(); 145 str = bd.toString(); 146 147 String exp = ""; 148 if (i < cs.length) { 149 exp = new String(cs, i, cs.length - i); 150 } 151 return str + exp + ' ' + u.getName(); 152 } 153 154 public Number getValue() { 155 return value; 156 } 157 158 public Unit<Q> getUnit() { 159 return unit; 160 } 161 162 public Scale getScale() { 163 return scale; 164 } 165 166 @Override 167 public boolean isEquivalentTo(Quantity<Q> that) { 168 return this.compareTo(that) == 0; 169 } 170}