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 }