001    /*
002     * JBoss DNA (http://www.jboss.org/dna)
003     * See the COPYRIGHT.txt file distributed with this work for information
004     * regarding copyright ownership.  Some portions may be licensed
005     * to Red Hat, Inc. under one or more contributor license agreements.
006     * See the AUTHORS.txt file in the distribution for a full listing of 
007     * individual contributors. 
008     *
009     * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
010     * is licensed to you under the terms of the GNU Lesser General Public License as
011     * published by the Free Software Foundation; either version 2.1 of
012     * the License, or (at your option) any later version.
013     *
014     * JBoss DNA is distributed in the hope that it will be useful,
015     * but WITHOUT ANY WARRANTY; without even the implied warranty of
016     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
017     * Lesser General Public License for more details.
018     *
019     * You should have received a copy of the GNU Lesser General Public
020     * License along with this software; if not, write to the Free
021     * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
022     * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
023     */
024    package org.jboss.dna.common.math;
025    
026    import java.math.BigDecimal;
027    import java.util.Comparator;
028    import java.util.Random;
029    
030    /**
031     * The set of mathematic operations for a particular class of values. This is useful for generic classes that must work with one
032     * of the {@link Number} subclasses.
033     * @param <T> the numeric class, usually a subclass of {@link Number} (although this is not required)
034     */
035    public interface MathOperations<T> {
036    
037        /**
038         * Return the class that these operations operate upon.
039         * @return the class
040         */
041        public Class<T> getOperandClass();
042    
043        /**
044         * Add the two operands and return the sum. The {@link #createZeroValue() zero value} is used in place of any operand that is
045         * null.
046         * @param value1 the first operand
047         * @param value2 the second operand
048         * @return the sum of the two operands.
049         */
050        public T add( T value1, T value2 );
051    
052        /**
053         * Subtract the second operand from the first, and return the difference. The {@link #createZeroValue() zero value} is used in
054         * place of any operand that is null.
055         * @param value1 the first operand
056         * @param value2 the second operand
057         * @return the difference between the two operands.
058         */
059        public T subtract( T value1, T value2 );
060    
061        /**
062         * Multiply the two operands and return the product. The {@link #createZeroValue() zero value} is used in place of any operand
063         * that is null.
064         * @param value1 the first operand
065         * @param value2 the second operand
066         * @return the product of the two operands.
067         */
068        public T multiply( T value1, T value2 );
069    
070        /**
071         * Divide the first operand by the second, and return the result. The {@link #createZeroValue() zero value} is used in place
072         * of any operand that is null.
073         * @param value1 the first operand
074         * @param value2 the second operand
075         * @return the result of the division
076         */
077        public double divide( T value1, T value2 );
078    
079        /**
080         * Negate the supplied operand. The {@link #createZeroValue() zero value} is used in place of any operand that is null.
081         * @param value the value that is to be negated
082         * @return the result of the negation
083         */
084        public T negate( T value );
085    
086        /**
087         * Increment the supplied operand by 1. (Note, the exact meaning of "1" is dependent upon the particular
088         * {@link #getOperandClass() operand class}. The {@link #createZeroValue() zero value} is used in place of any operand that
089         * is null.
090         * @param value the value that is to be incremented
091         * @return the incremented value
092         */
093        public T increment( T value );
094    
095        /**
096         * Compare the two operands and return the one that is larger. A null value is considered smaller than non-null values
097         * (including 0).
098         * @param value1 the first operand
099         * @param value2 the second operand
100         * @return the larger of the two operands
101         */
102        public T maximum( T value1, T value2 );
103    
104        /**
105         * Compare the two operands and return the one that is smaller. A null value is considered larger than non-null values
106         * (including 0).
107         * @param value1 the first operand
108         * @param value2 the second operand
109         * @return the smaller of the two operands
110         */
111        public T minimum( T value1, T value2 );
112    
113        /**
114         * Compare the two operands and return an integer that describes whether the first value is larger, smaller or the same as the
115         * second value. The semantics are identical to those of {@link Comparable}. The {@link #createZeroValue() zero value} is
116         * used in place of any operand that is null.
117         * @param value1 the first operand
118         * @param value2 the second operand
119         * @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
120         * equal.
121         */
122        public int compare( T value1, T value2 );
123    
124        /**
125         * Create a {@link BigDecimal} representation of the supplied value.
126         * @param value the value that is to be converted to a BigDecimal
127         * @return the BigDecimal representation, or null if <code>value</code> is null
128         */
129        public BigDecimal asBigDecimal( T value );
130    
131        /**
132         * Convert the {@link BigDecimal} representation into the natural object representation. This may result in loss of some data
133         * (e.g., converting a decimal to an integer results in the loss of the fractional part of the number).
134         * @param value the BigDecimal value
135         * @return the natural representation, or null if <code>value</code> is null
136         */
137        public T fromBigDecimal( BigDecimal value );
138    
139        /**
140         * Convert the value to a double. This may result in a loss of information depending upon the
141         * {@link #getOperandClass() operand class}.
142         * @param value the value
143         * @return the representation as a double
144         */
145        public double doubleValue( T value );
146    
147        /**
148         * Convert the value to a float. This may result in a loss of information depending upon the
149         * {@link #getOperandClass() operand class}.
150         * @param value the value
151         * @return the representation as a float
152         */
153        public float floatValue( T value );
154    
155        /**
156         * Convert the value to an integer. This may result in a loss of information depending upon the
157         * {@link #getOperandClass() operand class}.
158         * @param value the value
159         * @return the representation as an integer
160         */
161        public int intValue( T value );
162    
163        /**
164         * Convert the value to a short. This may result in a loss of information depending upon the
165         * {@link #getOperandClass() operand class}.
166         * @param value the value
167         * @return the representation as a short
168         */
169        public short shortValue( T value );
170    
171        /**
172         * Convert the value to a long integer. This may result in a loss of information depending upon the
173         * {@link #getOperandClass() operand class}.
174         * @param value the value
175         * @return the representation as a long
176         */
177        public long longValue( T value );
178    
179        /**
180         * Create the object form of the "zero value". This is often used to create an uninitialized object.
181         * @return the object that represents zero.
182         */
183        public T createZeroValue();
184    
185        /**
186         * Convert the integer representation into the natural object representation.
187         * @param value the integer value
188         * @return the object representation of the integer
189         */
190        public T create( int value );
191    
192        /**
193         * Convert the long representation into the natural object representation.
194         * @param value the long value
195         * @return the object representation of the long integer
196         */
197        public T create( long value );
198    
199        /**
200         * Convert the double representation into the natural object representation.
201         * @param value the double value
202         * @return the object representation of the floating point number
203         */
204        public T create( double value );
205    
206        /**
207         * Return the square root of the supplied operand.
208         * @param value the value whose root is to be found; may not be null or 0
209         * @return the square root of the value
210         */
211        public double sqrt( T value );
212    
213        /**
214         * Return a {@link Comparator Comparator<T>} for this {@link #getOperandClass() operand class}. The implementation is free to
215         * return the same comparator instance from multiple invocations of this method.
216         * @return a comparator
217         */
218        public Comparator<T> getComparator();
219    
220        /**
221         * Get the exponent if the number were written in exponential form.
222         * @param value the value
223         * @return the scale
224         */
225        public int getExponentInScientificNotation( T value );
226    
227        /**
228         * Round up the supplied value to the desired scale. This process works (conceptually) by shifting the decimal point of the
229         * value by <code>decimalShift</code> places, rounding, and then shifting the decimal point of the rounded value by
230         * <code>-decimalShift</code>
231         * <p>
232         * For example, consider the number 10.000354. This can be rounded to 10.0004 by calling this method and supplying the value
233         * and an "exponentToKeep" value of -4.
234         * </p>
235         * @param value the value to be rounded
236         * @param decimalShift the number of places the decimal point should be shifted before rounding
237         * @return the rounded value
238         */
239        public T roundUp( T value, int decimalShift );
240    
241        /**
242         * Round down the supplied value to the desired scale. This process works (conceptually) by shifting the decimal point of the
243         * value by <code>decimalShift</code> places, rounding, and then shifting the decimal point of the rounded value by
244         * <code>-decimalShift</code>
245         * <p>
246         * For example, consider the number 10.000354. This can be rounded to 10.0003 by calling this method and supplying the value
247         * and an "exponentToKeep" value of -4.
248         * </p>
249         * @param value the value to be rounded
250         * @param decimalShift the number of places the decimal point should be shifted before rounding
251         * @return the rounded value
252         */
253        public T roundDown( T value, int decimalShift );
254    
255        public T keepSignificantFigures( T value, int numSigFigs );
256    
257        /**
258         * Generate a random instance within the specified range.
259         * @param minimum the minimum value, or null if the {@link #createZeroValue() zero-value} should be used for the minimum
260         * @param maximum the maximum value, or null if the {@link #createZeroValue() zero-value} should be used for the maximum
261         * @param rng the random number generator to use
262         * @return an instance of the {@link #getOperandClass() operand class} placed within the desired range using a random
263         * distribution, or null if this class does not support generating random instances
264         */
265        public T random( T minimum, T maximum, Random rng );
266    }