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