View Javadoc

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 }