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