1 package org.djunits.value.base;
2
3 import org.djunits.unit.Unit;
4 import org.djunits.value.Value;
5 import org.djutils.exceptions.Throw;
6
7 /**
8 * Scalar to distinguish a scalar from vectors and matrices.
9 * <p>
10 * Copyright (c) 2019-2025 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
11 * BSD-style license. See <a href="https://djunits.org/docs/license.html">DJUNITS License</a>.
12 * </p>
13 * @author <a href="https://www.tudelft.nl/averbraeck" target="_blank">Alexander Verbraeck</a>
14 * @param <U> the unit
15 * @param <S> the scalar type with the given unit
16 */
17 public abstract class Scalar<U extends Unit<U>, S extends Scalar<U, S>> extends Number implements Value<U, S>, Comparable<S>
18 {
19 /** */
20 private static final long serialVersionUID = 20150626L;
21
22 /** The display unit of this AbstractScalar. */
23 private U displayUnit;
24
25 /**
26 * Construct a new Scalar.
27 * @param displayUnit the unit of the new AbstractScalar
28 */
29 protected Scalar(final U displayUnit)
30 {
31 Throw.whenNull(displayUnit, "display unit cannot be null");
32 this.displayUnit = displayUnit;
33 }
34
35 @Override
36 public final U getDisplayUnit()
37 {
38 return this.displayUnit;
39 }
40
41 @SuppressWarnings("unchecked")
42 @Override
43 public S setDisplayUnit(final U newUnit)
44 {
45 Throw.whenNull(newUnit, "newUnit may not be null");
46 this.displayUnit = newUnit;
47 return (S) this;
48 }
49
50 // No hashcode or equals -- has to be implemented on a deeper level
51
52 /**
53 * Test if this DoubleScalar is less than another DoubleScalar.
54 * @param o the right hand side operand of the comparison
55 * @return true if this is less than o; false otherwise
56 */
57 public abstract boolean lt(S o);
58
59 /**
60 * Test if this DoubleScalar is less than or equal to another DoubleScalar.
61 * @param o the right hand side operand of the comparison
62 * @return true if this is less than or equal to o; false otherwise
63 */
64 public abstract boolean le(S o);
65
66 /**
67 * Test if this DoubleScalar is greater than another DoubleScalar.
68 * @param o the right hand side operand of the comparison
69 * @return true if this is greater than o; false otherwise
70 */
71 public abstract boolean gt(S o);
72
73 /**
74 * Test if this DoubleScalar is greater than or equal to another DoubleScalar.
75 * @param o the right hand side operand of the comparison
76 * @return true if this is greater than or equal to o; false otherwise
77 */
78 public abstract boolean ge(S o);
79
80 /**
81 * Test if this DoubleScalar is equal to another DoubleScalar.
82 * @param o the right hand side operand of the comparison
83 * @return true if this is equal to o; false otherwise
84 */
85 public abstract boolean eq(S o);
86
87 /**
88 * Test if this DoubleScalar is not equal to another DoubleScalar.
89 * @param o the right hand side operand of the comparison
90 * @return true if this is not equal to o; false otherwise
91 */
92 public abstract boolean ne(S o);
93
94 /**
95 * Test if this DoubleScalar is less than 0.0.
96 * @return true if this is less than 0.0; false if this is not less than 0.0
97 */
98 public abstract boolean lt0();
99
100 /**
101 * Test if this DoubleScalar is less than or equal to 0.0.
102 * @return true if this is less than or equal to 0.0; false if this is not less than or equal to 0.0
103 */
104 public abstract boolean le0();
105
106 /**
107 * Test if this DoubleScalar is greater than 0.0.
108 * @return true if this is greater than 0.0; false if this is not greater than 0.0
109 */
110 public abstract boolean gt0();
111
112 /**
113 * Test if this DoubleScalar is greater than or equal to 0.0.
114 * @return true if this is greater than or equal to 0.0; false if this is not greater than or equal to 0.0
115 */
116 public abstract boolean ge0();
117
118 /**
119 * Test if this DoubleScalar is equal to 0.0.
120 * @return true if this is equal to 0.0; false if this is not equal to 0.0
121 */
122 public abstract boolean eq0();
123
124 /**
125 * Test if this DoubleScalar is not equal to 0.0.
126 * @return true if this is not equal to 0.0; false if this is equal to 0.0
127 */
128 public abstract boolean ne0();
129
130 /**
131 * Concise textual representation of this value, without the engineering formatting, so without trailing zeroes. A space is
132 * added between the number and the unit.
133 * @return a String with the value with the default textual representation of the unit attached.
134 */
135 public abstract String toTextualString();
136
137 /**
138 * Concise textual representation of this value, without the engineering formatting, so without trailing zeroes. A space is
139 * added between the number and the unit.
140 * @param withDisplayUnit the display unit for the value
141 * @return a String with the value with the default textual representation of the provided unit attached.
142 */
143 public abstract String toTextualString(U withDisplayUnit);
144
145 /**
146 * Concise display description of this value, without the engineering formatting, so without trailing zeroes. A space is
147 * added between the number and the unit.
148 * @return a String with the value with the default display representation of the unit attached.
149 */
150 public abstract String toDisplayString();
151
152 /**
153 * Concise display description of this value, without the engineering formatting, so without trailing zeroes. A space is
154 * added between the number and the unit.
155 * @param withDisplayUnit the display unit for the value
156 * @return a String with the value with the default display representation of the provided unit attached.
157 */
158 public abstract String toDisplayString(U withDisplayUnit);
159
160 /**
161 * Format a string according to the current locale and the standard (minimized) format, such as "3.14" or "300.0".
162 * @param d the number to format
163 * @return the formatted number using the current Locale
164 */
165 public String format(final double d)
166 {
167 if (d < 1E-5 || d > 1E5)
168 {
169 return format(d, "%E");
170 }
171 return format(d, "%f");
172 }
173
174 /**
175 * Format a string according to the current locale and the provided format string.
176 * @param d the number to format
177 * @param format the formatting string to use for the number
178 * @return the formatted number using the current Locale and the format string
179 */
180 public String format(final double d, final String format)
181 {
182 String s = String.format(format, d);
183 if (s.contains("e") || s.contains("E"))
184 {
185 return s;
186 }
187 while (s.endsWith("0") && s.length() > 2)
188 {
189 s = s.substring(0, s.length() - 1);
190 }
191 String last = s.substring(s.length() - 1);
192 if (!"01234567890".contains(last))
193 {
194 s += "0";
195 }
196 return s;
197 }
198
199 }