1 /*
2 * ModeShape (http://www.modeshape.org)
3 * See the COPYRIGHT.txt file distributed with this work for information
4 * regarding copyright ownership. Some portions may be licensed
5 * to Red Hat, Inc. under one or more contributor license agreements.
6 * See the AUTHORS.txt file in the distribution for a full listing of
7 * individual contributors.
8 *
9 * ModeShape is free software. Unless otherwise indicated, all code in ModeShape
10 * is licensed to you under the terms of the GNU Lesser General Public License as
11 * published by the Free Software Foundation; either version 2.1 of
12 * the License, or (at your option) any later version.
13 *
14 * ModeShape is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this software; if not, write to the Free
21 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
23 */
24 package org.modeshape.common.math;
25
26 import java.math.BigDecimal;
27 import java.util.Comparator;
28 import java.util.Random;
29 import net.jcip.annotations.Immutable;
30
31 /**
32 * The set of mathematic operations for a particular class of values. This is useful for generic classes that must work with one
33 * of the {@link Number} subclasses.
34 *
35 * @param <T> the numeric class, usually a subclass of {@link Number} (although this is not required)
36 */
37 @Immutable
38 public interface MathOperations<T> {
39
40 /**
41 * Return the class that these operations operate upon.
42 *
43 * @return the class
44 */
45 public Class<T> getOperandClass();
46
47 /**
48 * Add the two operands and return the sum. The {@link #createZeroValue() zero value} is used in place of any operand that is
49 * null.
50 *
51 * @param value1 the first operand
52 * @param value2 the second operand
53 * @return the sum of the two operands.
54 */
55 public T add( T value1,
56 T value2 );
57
58 /**
59 * Subtract the second operand from the first, and return the difference. The {@link #createZeroValue() zero value} is used in
60 * place of any operand that is null.
61 *
62 * @param value1 the first operand
63 * @param value2 the second operand
64 * @return the difference between the two operands.
65 */
66 public T subtract( T value1,
67 T value2 );
68
69 /**
70 * Multiply the two operands and return the product. The {@link #createZeroValue() zero value} is used in place of any operand
71 * that is null.
72 *
73 * @param value1 the first operand
74 * @param value2 the second operand
75 * @return the product of the two operands.
76 */
77 public T multiply( T value1,
78 T value2 );
79
80 /**
81 * Divide the first operand by the second, and return the result. The {@link #createZeroValue() zero value} is used in place
82 * of any operand that is null.
83 *
84 * @param value1 the first operand
85 * @param value2 the second operand
86 * @return the result of the division
87 */
88 public double divide( T value1,
89 T value2 );
90
91 /**
92 * Negate the supplied operand. The {@link #createZeroValue() zero value} is used in place of any operand that is null.
93 *
94 * @param value the value that is to be negated
95 * @return the result of the negation
96 */
97 public T negate( T value );
98
99 /**
100 * Increment the supplied operand by 1. (Note, the exact meaning of "1" is dependent upon the particular
101 * {@link #getOperandClass() operand class}. The {@link #createZeroValue() zero value} is used in place of any operand that is
102 * null.
103 *
104 * @param value the value that is to be incremented
105 * @return the incremented value
106 */
107 public T increment( T value );
108
109 /**
110 * Compare the two operands and return the one that is larger. A null value is considered smaller than non-null values
111 * (including 0).
112 *
113 * @param value1 the first operand
114 * @param value2 the second operand
115 * @return the larger of the two operands
116 */
117 public T maximum( T value1,
118 T value2 );
119
120 /**
121 * Compare the two operands and return the one that is smaller. A null value is considered larger than non-null values
122 * (including 0).
123 *
124 * @param value1 the first operand
125 * @param value2 the second operand
126 * @return the smaller of the two operands
127 */
128 public T minimum( T value1,
129 T value2 );
130
131 /**
132 * Compare the two operands and return an integer that describes whether the first value is larger, smaller or the same as the
133 * second value. The semantics are identical to those of {@link Comparable}. The {@link #createZeroValue() zero value} is used
134 * in place of any operand that is null.
135 *
136 * @param value1 the first operand
137 * @param value2 the second operand
138 * @return -1 if the first value is smaller than the second, 1 if the first value is larger than the second, or 0 if they are
139 * equal.
140 */
141 public int compare( T value1,
142 T value2 );
143
144 /**
145 * Create a {@link BigDecimal} representation of the supplied value.
146 *
147 * @param value the value that is to be converted to a BigDecimal
148 * @return the BigDecimal representation, or null if <code>value</code> is null
149 */
150 public BigDecimal asBigDecimal( T value );
151
152 /**
153 * Convert the {@link BigDecimal} representation into the natural object representation. This may result in loss of some data
154 * (e.g., converting a decimal to an integer results in the loss of the fractional part of the number).
155 *
156 * @param value the BigDecimal value
157 * @return the natural representation, or null if <code>value</code> is null
158 */
159 public T fromBigDecimal( BigDecimal value );
160
161 /**
162 * Convert the value to a double. This may result in a loss of information depending upon the {@link #getOperandClass()
163 * operand class}.
164 *
165 * @param value the value
166 * @return the representation as a double
167 */
168 public double doubleValue( T value );
169
170 /**
171 * Convert the value to a float. This may result in a loss of information depending upon the {@link #getOperandClass() operand
172 * class}.
173 *
174 * @param value the value
175 * @return the representation as a float
176 */
177 public float floatValue( T value );
178
179 /**
180 * Convert the value to an integer. This may result in a loss of information depending upon the {@link #getOperandClass()
181 * operand class}.
182 *
183 * @param value the value
184 * @return the representation as an integer
185 */
186 public int intValue( T value );
187
188 /**
189 * Convert the value to a short. This may result in a loss of information depending upon the {@link #getOperandClass() operand
190 * class}.
191 *
192 * @param value the value
193 * @return the representation as a short
194 */
195 public short shortValue( T value );
196
197 /**
198 * Convert the value to a long integer. This may result in a loss of information depending upon the {@link #getOperandClass()
199 * operand class}.
200 *
201 * @param value the value
202 * @return the representation as a long
203 */
204 public long longValue( T value );
205
206 /**
207 * Create the object form of the "zero value". This is often used to create an uninitialized object.
208 *
209 * @return the object that represents zero.
210 */
211 public T createZeroValue();
212
213 /**
214 * Convert the integer representation into the natural object representation.
215 *
216 * @param value the integer value
217 * @return the object representation of the integer
218 */
219 public T create( int value );
220
221 /**
222 * Convert the long representation into the natural object representation.
223 *
224 * @param value the long value
225 * @return the object representation of the long integer
226 */
227 public T create( long value );
228
229 /**
230 * Convert the double representation into the natural object representation.
231 *
232 * @param value the double value
233 * @return the object representation of the floating point number
234 */
235 public T create( double value );
236
237 /**
238 * Return the square root of the supplied operand.
239 *
240 * @param value the value whose root is to be found; may not be null or 0
241 * @return the square root of the value
242 */
243 public double sqrt( T value );
244
245 /**
246 * Return a {@link Comparator Comparator<T>} for this {@link #getOperandClass() operand class}. The implementation is free to
247 * return the same comparator instance from multiple invocations of this method.
248 *
249 * @return a comparator
250 */
251 public Comparator<T> getComparator();
252
253 /**
254 * Get the exponent if the number were written in exponential form.
255 *
256 * @param value the value
257 * @return the scale
258 */
259 public int getExponentInScientificNotation( T value );
260
261 /**
262 * Round up the supplied value to the desired scale. This process works (conceptually) by shifting the decimal point of the
263 * value by <code>decimalShift</code> places, rounding, and then shifting the decimal point of the rounded value by
264 * <code>-decimalShift</code>
265 * <p>
266 * For example, consider the number 10.000354. This can be rounded to 10.0004 by calling this method and supplying the value
267 * and an "exponentToKeep" value of -4.
268 * </p>
269 *
270 * @param value the value to be rounded
271 * @param decimalShift the number of places the decimal point should be shifted before rounding
272 * @return the rounded value
273 */
274 public T roundUp( T value,
275 int decimalShift );
276
277 /**
278 * Round down the supplied value to the desired scale. This process works (conceptually) by shifting the decimal point of the
279 * value by <code>decimalShift</code> places, rounding, and then shifting the decimal point of the rounded value by
280 * <code>-decimalShift</code>
281 * <p>
282 * For example, consider the number 10.000354. This can be rounded to 10.0003 by calling this method and supplying the value
283 * and an "exponentToKeep" value of -4.
284 * </p>
285 *
286 * @param value the value to be rounded
287 * @param decimalShift the number of places the decimal point should be shifted before rounding
288 * @return the rounded value
289 */
290 public T roundDown( T value,
291 int decimalShift );
292
293 public T keepSignificantFigures( T value,
294 int numSigFigs );
295
296 /**
297 * Generate a random instance within the specified range.
298 *
299 * @param minimum the minimum value, or null if the {@link #createZeroValue() zero-value} should be used for the minimum
300 * @param maximum the maximum value, or null if the {@link #createZeroValue() zero-value} should be used for the maximum
301 * @param rng the random number generator to use
302 * @return an instance of the {@link #getOperandClass() operand class} placed within the desired range using a random
303 * distribution, or null if this class does not support generating random instances
304 */
305 public T random( T minimum,
306 T maximum,
307 Random rng );
308 }