View Javadoc
1   package org.djunits.value.vfloat.scalar.base;
2   
3   import org.djunits.unit.Unit;
4   import org.djunits.unit.si.SIPrefixes;
5   import org.djunits.value.Absolute;
6   import org.djunits.value.AbstractScalar;
7   import org.djunits.value.formatter.Format;
8   import org.djunits.value.util.ValueUtil;
9   
10  /**
11   * The most basic abstract class for the FloatScalar.
12   * <p>
13   * Copyright (c) 2013-2023 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
14   * BSD-style license. See <a href="https://djunits.org/docs/license.html">DJUNITS License</a>.
15   * </p>
16   * @author <a href="https://www.tudelft.nl/averbraeck">Alexander Verbraeck</a>
17   * @author <a href="https://www.tudelft.nl/staff/p.knoppers/">Peter Knoppers</a>
18   * @param <U> the unit
19   * @param <S> the type
20   */
21  public abstract class AbstractFloatScalar<U extends Unit<U>, S extends AbstractFloatScalar<U, S>> extends AbstractScalar<U, S>
22          implements FloatScalarInterface<U, S>
23  {
24      /** */
25      private static final long serialVersionUID = 20161015L;
26  
27      /** The value, stored in the standard SI unit. */
28      @SuppressWarnings("checkstyle:visibilitymodifier")
29      public final float si;
30  
31      /**
32       * Construct a new AbstractFloatScalar.
33       * @param unit U; the unit
34       * @param si float; the si value to store
35       */
36      AbstractFloatScalar(final U unit, final float si)
37      {
38          super(unit);
39          this.si = si;
40      }
41  
42      /** {@inheritDoc} */
43      @Override
44      public final float getSI()
45      {
46          return this.si;
47      }
48  
49      /** {@inheritDoc} */
50      @Override
51      public final float getInUnit()
52      {
53          return (float) ValueUtil.expressAsUnit(getSI(), getDisplayUnit());
54      }
55  
56      /** {@inheritDoc} */
57      @Override
58      public final float getInUnit(final U targetUnit)
59      {
60          return (float) ValueUtil.expressAsUnit(getSI(), targetUnit);
61      }
62  
63      /** {@inheritDoc} */
64      @Override
65      public final boolean lt(final S o)
66      {
67          return this.getSI() < o.getSI();
68      }
69  
70      /** {@inheritDoc} */
71      @Override
72      public final boolean le(final S o)
73      {
74          return this.getSI() <= o.getSI();
75      }
76  
77      /** {@inheritDoc} */
78      @Override
79      public final boolean gt(final S o)
80      {
81          return this.getSI() > o.getSI();
82      }
83  
84      /** {@inheritDoc} */
85      @Override
86      public final boolean ge(final S o)
87      {
88          return this.getSI() >= o.getSI();
89      }
90  
91      /** {@inheritDoc} */
92      @Override
93      public final boolean eq(final S o)
94      {
95          return this.getSI() == o.getSI();
96      }
97  
98      /** {@inheritDoc} */
99      @Override
100     public final boolean ne(final S o)
101     {
102         return this.getSI() != o.getSI();
103     }
104 
105     /** {@inheritDoc} */
106     @Override
107     public final boolean lt0()
108     {
109         return this.getSI() < 0.0;
110     }
111 
112     /** {@inheritDoc} */
113     @Override
114     public final boolean le0()
115     {
116         return this.getSI() <= 0.0;
117     }
118 
119     /** {@inheritDoc} */
120     @Override
121     public final boolean gt0()
122     {
123         return this.getSI() > 0.0;
124     }
125 
126     /** {@inheritDoc} */
127     @Override
128     public final boolean ge0()
129     {
130         return this.getSI() >= 0.0;
131     }
132 
133     /** {@inheritDoc} */
134     @Override
135     public final boolean eq0()
136     {
137         return this.getSI() == 0.0;
138     }
139 
140     /** {@inheritDoc} */
141     @Override
142     public final boolean ne0()
143     {
144         return this.getSI() != 0.0;
145     }
146 
147     /** {@inheritDoc} */
148     @Override
149     public final int compareTo(final S o)
150     {
151         return Float.compare(this.getSI(), o.getSI());
152     }
153 
154     /** {@inheritDoc} */
155     @Override
156     public int intValue()
157     {
158         return (int) this.getSI();
159     }
160 
161     /** {@inheritDoc} */
162     @Override
163     public long longValue()
164     {
165         return (long) this.getSI();
166     }
167 
168     /** {@inheritDoc} */
169     @Override
170     public float floatValue()
171     {
172         return this.getSI();
173     }
174 
175     /** {@inheritDoc} */
176     @Override
177     public double doubleValue()
178     {
179         return this.getSI();
180     }
181 
182     /**********************************************************************************/
183     /********************************* GENERIC METHODS ********************************/
184     /**********************************************************************************/
185 
186     /** {@inheritDoc} */
187     @Override
188     public String toString()
189     {
190         return toString(getDisplayUnit(), false, true);
191     }
192 
193     /** {@inheritDoc} */
194     @Override
195     public String toString(final U displayUnit)
196     {
197         return toString(displayUnit, false, true);
198     }
199 
200     /** {@inheritDoc} */
201     @Override
202     public String toString(final boolean verbose, final boolean withUnit)
203     {
204         return toString(getDisplayUnit(), verbose, withUnit);
205     }
206 
207     /** {@inheritDoc} */
208     @Override
209     public String toString(final U displayUnit, final boolean verbose, final boolean withUnit)
210     {
211         StringBuffer buf = new StringBuffer();
212         if (verbose)
213         {
214             buf.append(this instanceof Absolute ? "Abs " : "Rel ");
215         }
216         float d = (float) ValueUtil.expressAsUnit(getSI(), displayUnit);
217         buf.append(Format.format(d));
218         if (withUnit)
219         {
220             buf.append(" "); // Insert one space as prescribed by SI writing conventions
221             buf.append(displayUnit.getLocalizedDisplayAbbreviation());
222         }
223         return buf.toString();
224     }
225 
226     /**
227      * Format this AbstractDoubleScalar in SI unit using prefixes when possible. If the value is too small or too large,
228      * e-notation and the plain SI unit are used.
229      * @return String; formatted value of this AbstractDoubleScalar
230      */
231     public String toStringSIPrefixed()
232     {
233         return toStringSIPrefixed(-24, 26);
234     }
235 
236     /**
237      * Format this AbstractDoubleScalar in SI unit using prefixes when possible and within the specified size range. If the
238      * value is too small or too large, e-notation and the plain SI unit are used.
239      * @param smallestPower int; the smallest exponent value that will be written using an SI prefix
240      * @param biggestPower int; the largest exponent value that will be written using an SI prefix
241      * @return String; formatted value of this AbstractDoubleScalar
242      */
243     public String toStringSIPrefixed(final int smallestPower, final int biggestPower)
244     {
245         // Override this method for weights, nonlinear units and DimensionLess.
246         if (!Double.isFinite(this.si))
247         {
248             return toString(getDisplayUnit().getStandardUnit());
249         }
250         // PK: I can't think of an easier way to figure out what the exponent will be; rounding of the mantissa to the available
251         // width makes this hard; This feels like an expensive way.
252         String check = String.format(this.si >= 0 ? "%10.8E" : "%10.7E", this.si);
253         int exponent = Integer.parseInt(check.substring(check.indexOf("E") + 1));
254         if (exponent < -24 || exponent < smallestPower || exponent > 24 + 2 || exponent > biggestPower)
255         {
256             // Out of SI prefix range; do not scale.
257             return String.format(this.si >= 0 ? "%10.4E" : "%10.3E", this.si) + " "
258                     + getDisplayUnit().getStandardUnit().getId();
259         }
260         Integer roundedExponent = (int) Math.ceil((exponent - 2.0) / 3) * 3;
261         // System.out.print(String.format("exponent=%d; roundedExponent=%d ", exponent, roundedExponent));
262         String key =
263                 SIPrefixes.FACTORS.get(roundedExponent).getDefaultTextualPrefix() + getDisplayUnit().getStandardUnit().getId();
264         U displayUnit = getDisplayUnit().getQuantity().getUnitByAbbreviation(key);
265         return toString(displayUnit);
266     }
267 
268     /** {@inheritDoc} */
269     @Override
270     public String toTextualString()
271     {
272         return toTextualString(getDisplayUnit());
273     }
274 
275     /** {@inheritDoc} */
276     @Override
277     public String toTextualString(final U displayUnit)
278     {
279         float f = (float) ValueUtil.expressAsUnit(getSI(), displayUnit);
280         return format(f) + " " + displayUnit.getLocalizedTextualAbbreviation();
281     }
282 
283     /** {@inheritDoc} */
284     @Override
285     public String toDisplayString()
286     {
287         return toDisplayString(getDisplayUnit());
288     }
289 
290     /** {@inheritDoc} */
291     @Override
292     public String toDisplayString(final U displayUnit)
293     {
294         float f = (float) ValueUtil.expressAsUnit(getSI(), displayUnit);
295         return format(f) + " " + displayUnit.getLocalizedDisplayAbbreviation();
296     }
297 
298     /** {@inheritDoc} */
299     @Override
300     @SuppressWarnings("checkstyle:designforextension")
301     public int hashCode()
302     {
303         final int prime = 31;
304         int result = getDisplayUnit().getStandardUnit().hashCode();
305         long temp;
306         temp = Float.floatToIntBits(this.getSI());
307         result = prime * result + (int) (temp ^ (temp >>> 32));
308         return result;
309     }
310 
311     /** {@inheritDoc} */
312     @Override
313     @SuppressWarnings({"checkstyle:designforextension", "checkstyle:needbraces", "unchecked"})
314     public boolean equals(final Object obj)
315     {
316         if (this == obj)
317             return true;
318         if (obj == null)
319             return false;
320         if (getClass() != obj.getClass())
321             return false;
322         AbstractFloatScalar<U, S> other = (AbstractFloatScalar<U, S>) obj;
323         if (!getDisplayUnit().getStandardUnit().equals(other.getDisplayUnit().getStandardUnit()))
324             return false;
325         if (Float.floatToIntBits(this.getSI()) != Float.floatToIntBits(other.getSI()))
326             return false;
327         return true;
328     }
329 
330 }