001/* 002 * ModeShape (http://www.modeshape.org) 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.modeshape.common.math; 017 018import java.math.BigDecimal; 019import java.util.Comparator; 020import java.util.Random; 021import org.modeshape.common.annotation.Immutable; 022 023/** 024 * The set of mathematic operations for a particular class of values. This is useful for generic classes that must work with one 025 * of the {@link Number} subclasses. 026 * 027 * @param <T> the numeric class, usually a subclass of {@link Number} (although this is not required) 028 */ 029@Immutable 030public interface MathOperations<T> { 031 032 /** 033 * Return the class that these operations operate upon. 034 * 035 * @return the class 036 */ 037 public Class<T> getOperandClass(); 038 039 /** 040 * Add the two operands and return the sum. The {@link #createZeroValue() zero value} is used in place of any operand that is 041 * null. 042 * 043 * @param value1 the first operand 044 * @param value2 the second operand 045 * @return the sum of the two operands. 046 */ 047 public T add( T value1, 048 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 * 054 * @param value1 the first operand 055 * @param value2 the second operand 056 * @return the difference between the two operands. 057 */ 058 public T subtract( T value1, 059 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 * 065 * @param value1 the first operand 066 * @param value2 the second operand 067 * @return the product of the two operands. 068 */ 069 public T multiply( T value1, 070 T value2 ); 071 072 /** 073 * Divide the first operand by the second, and return the result. The {@link #createZeroValue() zero value} is used in place 074 * of any operand that is null. 075 * 076 * @param value1 the first operand 077 * @param value2 the second operand 078 * @return the result of the division 079 */ 080 public double divide( T value1, 081 T value2 ); 082 083 /** 084 * Negate the supplied operand. The {@link #createZeroValue() zero value} is used in place of any operand that is null. 085 * 086 * @param value the value that is to be negated 087 * @return the result of the negation 088 */ 089 public T negate( T value ); 090 091 /** 092 * Increment the supplied operand by 1. (Note, the exact meaning of "1" is dependent upon the particular 093 * {@link #getOperandClass() operand class}. The {@link #createZeroValue() zero value} is used in place of any operand that is 094 * null. 095 * 096 * @param value the value that is to be incremented 097 * @return the incremented value 098 */ 099 public T increment( T value ); 100 101 /** 102 * Compare the two operands and return the one that is larger. A null value is considered smaller than non-null values 103 * (including 0). 104 * 105 * @param value1 the first operand 106 * @param value2 the second operand 107 * @return the larger of the two operands 108 */ 109 public T maximum( T value1, 110 T value2 ); 111 112 /** 113 * Compare the two operands and return the one that is smaller. A null value is considered larger than non-null values 114 * (including 0). 115 * 116 * @param value1 the first operand 117 * @param value2 the second operand 118 * @return the smaller of the two operands 119 */ 120 public T minimum( T value1, 121 T value2 ); 122 123 /** 124 * Compare the two operands and return an integer that describes whether the first value is larger, smaller or the same as the 125 * second value. The semantics are identical to those of {@link Comparable}. The {@link #createZeroValue() zero value} is used 126 * in place of any operand that is null. 127 * 128 * @param value1 the first operand 129 * @param value2 the second operand 130 * @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 131 * equal. 132 */ 133 public int compare( T value1, 134 T value2 ); 135 136 /** 137 * Create a {@link BigDecimal} representation of the supplied value. 138 * 139 * @param value the value that is to be converted to a BigDecimal 140 * @return the BigDecimal representation, or null if <code>value</code> is null 141 */ 142 public BigDecimal asBigDecimal( T value ); 143 144 /** 145 * Convert the {@link BigDecimal} representation into the natural object representation. This may result in loss of some data 146 * (e.g., converting a decimal to an integer results in the loss of the fractional part of the number). 147 * 148 * @param value the BigDecimal value 149 * @return the natural representation, or null if <code>value</code> is null 150 */ 151 public T fromBigDecimal( BigDecimal value ); 152 153 /** 154 * Convert the value to a double. This may result in a loss of information depending upon the {@link #getOperandClass() 155 * operand class}. 156 * 157 * @param value the value 158 * @return the representation as a double 159 */ 160 public double doubleValue( T value ); 161 162 /** 163 * Convert the value to a float. This may result in a loss of information depending upon the {@link #getOperandClass() operand 164 * class}. 165 * 166 * @param value the value 167 * @return the representation as a float 168 */ 169 public float floatValue( T value ); 170 171 /** 172 * Convert the value to an integer. This may result in a loss of information depending upon the {@link #getOperandClass() 173 * operand class}. 174 * 175 * @param value the value 176 * @return the representation as an integer 177 */ 178 public int intValue( T value ); 179 180 /** 181 * Convert the value to a short. This may result in a loss of information depending upon the {@link #getOperandClass() operand 182 * class}. 183 * 184 * @param value the value 185 * @return the representation as a short 186 */ 187 public short shortValue( T value ); 188 189 /** 190 * Convert the value to a long integer. This may result in a loss of information depending upon the {@link #getOperandClass() 191 * operand class}. 192 * 193 * @param value the value 194 * @return the representation as a long 195 */ 196 public long longValue( T value ); 197 198 /** 199 * Create the object form of the "zero value". This is often used to create an uninitialized object. 200 * 201 * @return the object that represents zero. 202 */ 203 public T createZeroValue(); 204 205 /** 206 * Convert the integer representation into the natural object representation. 207 * 208 * @param value the integer value 209 * @return the object representation of the integer 210 */ 211 public T create( int value ); 212 213 /** 214 * Convert the long representation into the natural object representation. 215 * 216 * @param value the long value 217 * @return the object representation of the long integer 218 */ 219 public T create( long value ); 220 221 /** 222 * Convert the double representation into the natural object representation. 223 * 224 * @param value the double value 225 * @return the object representation of the floating point number 226 */ 227 public T create( double value ); 228 229 /** 230 * Return the square root of the supplied operand. 231 * 232 * @param value the value whose root is to be found; may not be null or 0 233 * @return the square root of the value 234 */ 235 public double sqrt( T value ); 236 237 /** 238 * Return a {@link Comparator Comparator<T>} for this {@link #getOperandClass() operand class}. The implementation is free to 239 * return the same comparator instance from multiple invocations of this method. 240 * 241 * @return a comparator 242 */ 243 public Comparator<T> getComparator(); 244 245 /** 246 * Get the exponent if the number were written in exponential form. 247 * 248 * @param value the value 249 * @return the scale 250 */ 251 public int getExponentInScientificNotation( T value ); 252 253 /** 254 * Round up the supplied value to the desired scale. This process works (conceptually) by shifting the decimal point of the 255 * value by <code>decimalShift</code> places, rounding, and then shifting the decimal point of the rounded value by 256 * <code>-decimalShift</code> 257 * <p> 258 * For example, consider the number 10.000354. This can be rounded to 10.0004 by calling this method and supplying the value 259 * and an "exponentToKeep" value of -4. 260 * </p> 261 * 262 * @param value the value to be rounded 263 * @param decimalShift the number of places the decimal point should be shifted before rounding 264 * @return the rounded value 265 */ 266 public T roundUp( T value, 267 int decimalShift ); 268 269 /** 270 * Round down the supplied value to the desired scale. This process works (conceptually) by shifting the decimal point of the 271 * value by <code>decimalShift</code> places, rounding, and then shifting the decimal point of the rounded value by 272 * <code>-decimalShift</code> 273 * <p> 274 * For example, consider the number 10.000354. This can be rounded to 10.0003 by calling this method and supplying the value 275 * and an "exponentToKeep" value of -4. 276 * </p> 277 * 278 * @param value the value to be rounded 279 * @param decimalShift the number of places the decimal point should be shifted before rounding 280 * @return the rounded value 281 */ 282 public T roundDown( T value, 283 int decimalShift ); 284 285 public T keepSignificantFigures( T value, 286 int numSigFigs ); 287 288 /** 289 * Generate a random instance within the specified range. 290 * 291 * @param minimum the minimum value, or null if the {@link #createZeroValue() zero-value} should be used for the minimum 292 * @param maximum the maximum value, or null if the {@link #createZeroValue() zero-value} should be used for the maximum 293 * @param rng the random number generator to use 294 * @return an instance of the {@link #getOperandClass() operand class} placed within the desired range using a random 295 * distribution, or null if this class does not support generating random instances 296 */ 297 public T random( T minimum, 298 T maximum, 299 Random rng ); 300}