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 {@link MathOperations math operations} for short numbers. 025 */ 026@Immutable 027public class ShortOperations implements MathOperations<Short>, Comparator<Short> { 028 029 @Override 030 public Class<Short> getOperandClass() { 031 return Short.class; 032 } 033 034 @Override 035 public Short add( Short value1, 036 Short value2 ) { 037 if (value1 == null) return value2 != null ? value2 : createZeroValue(); 038 if (value2 == null) return value1; 039 return (short)(value1 + value2); 040 } 041 042 @Override 043 public Short subtract( Short value1, 044 Short value2 ) { 045 if (value1 == null) return negate(value2); 046 if (value2 == null) return value1; 047 return (short)(value1 - value2); 048 } 049 050 @Override 051 public Short multiply( Short value1, 052 Short value2 ) { 053 if (value1 == null || value2 == null) return createZeroValue(); 054 return (short)(value1 * value2); 055 } 056 057 @Override 058 public double divide( Short value1, 059 Short value2 ) { 060 if (value1 == null || value2 == null) throw new IllegalArgumentException(); 061 return value1 / value2; 062 } 063 064 @Override 065 public Short negate( Short value ) { 066 if (value == null) return createZeroValue(); 067 return (short)(value * -1); 068 } 069 070 @Override 071 public Short increment( Short value ) { 072 if (value == null) return createZeroValue(); 073 return (short)(value + 1); 074 } 075 076 @Override 077 public Short maximum( Short value1, 078 Short value2 ) { 079 if (value1 == null) return value2; 080 if (value2 == null) return value1; 081 return (short)Math.max(value1, value2); 082 } 083 084 @Override 085 public Short minimum( Short value1, 086 Short value2 ) { 087 if (value1 == null) return value2; 088 if (value2 == null) return value1; 089 return (short)Math.min(value1, value2); 090 } 091 092 @Override 093 public int compare( Short value1, 094 Short value2 ) { 095 if (value1 == null) return value2 != null ? -1 : 0; 096 if (value2 == null) return 1; 097 return value1.compareTo(value2); 098 } 099 100 @Override 101 public BigDecimal asBigDecimal( Short value ) { 102 return value != null ? new BigDecimal(value) : null; 103 } 104 105 @Override 106 public Short fromBigDecimal( BigDecimal value ) { 107 return value != null ? value.shortValue() : null; 108 } 109 110 @Override 111 public Short createZeroValue() { 112 return 0; 113 } 114 115 @Override 116 public Short create( int value ) { 117 return (short)value; 118 } 119 120 @Override 121 public Short create( long value ) { 122 return (short)value; 123 } 124 125 @Override 126 public Short create( double value ) { 127 return (short)value; 128 } 129 130 @Override 131 public double sqrt( Short value ) { 132 return Math.sqrt(value); 133 } 134 135 @Override 136 public Comparator<Short> getComparator() { 137 return this; 138 } 139 140 @Override 141 public Short random( Short minimum, 142 Short maximum, 143 Random rng ) { 144 Short difference = subtract(maximum, minimum); 145 int increment = rng.nextInt(difference.intValue()); 146 return new Integer(minimum + increment).shortValue(); 147 } 148 149 @Override 150 public double doubleValue( Short value ) { 151 return value.doubleValue(); 152 } 153 154 @Override 155 public float floatValue( Short value ) { 156 return value.floatValue(); 157 } 158 159 @Override 160 public int intValue( Short value ) { 161 return value.intValue(); 162 } 163 164 @Override 165 public long longValue( Short value ) { 166 return value.longValue(); 167 } 168 169 @Override 170 public short shortValue( Short value ) { 171 return value.shortValue(); 172 } 173 174 @Override 175 public int getExponentInScientificNotation( Short value ) { 176 int v = Math.abs(value); 177 int exp = 0; 178 if (v > 1) { 179 while (v >= 10) { 180 v /= 10; 181 ++exp; 182 } 183 } else if (v < 1) { 184 while (v < 1) { 185 v *= 10; 186 --exp; 187 } 188 } 189 return exp; 190 } 191 192 @Override 193 public Short roundUp( Short value, 194 int decimalShift ) { 195 if (value == 0) return 0; 196 if (decimalShift >= 0) return value; 197 int shiftedValueP5 = Math.abs(value); 198 for (int i = 0; i != (-decimalShift - 1); ++i) 199 shiftedValueP5 /= 10; 200 shiftedValueP5 += 5l; 201 int shiftedValue = shiftedValueP5 / 10; 202 if (shiftedValue * 10l - shiftedValueP5 >= 5) ++shiftedValue; 203 shiftedValue *= Long.signum(value); 204 for (int i = 0; i != -decimalShift; ++i) 205 shiftedValue *= 10; 206 return (short)shiftedValue; 207 } 208 209 @Override 210 public Short roundDown( Short value, 211 int decimalShift ) { 212 if (value == 0) return 0; 213 if (decimalShift >= 0) return value; 214 int shiftedValue = Math.abs(value); 215 for (int i = 0; i != -decimalShift; ++i) 216 shiftedValue /= 10; 217 shiftedValue *= Long.signum(value); 218 for (int i = 0; i != -decimalShift; ++i) 219 shiftedValue *= 10; 220 return (short)shiftedValue; 221 } 222 223 @Override 224 public Short keepSignificantFigures( Short value, 225 int numSigFigs ) { 226 if (numSigFigs < 0) return value; 227 if (numSigFigs == 0) return 0; 228 int currentExp = getExponentInScientificNotation(value); 229 int decimalShift = -currentExp + numSigFigs - 1; 230 return roundUp(value, decimalShift); 231 } 232}