001    /*
002     * JBoss DNA (http://www.jboss.org/dna)
003     * See the COPYRIGHT.txt file distributed with this work for information
004     * regarding copyright ownership.  Some portions may be licensed
005     * to Red Hat, Inc. under one or more contributor license agreements.
006     * See the AUTHORS.txt file in the distribution for a full listing of 
007     * individual contributors. 
008     *
009     * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
010     * is licensed to you under the terms of the GNU Lesser General Public License as
011     * published by the Free Software Foundation; either version 2.1 of
012     * the License, or (at your option) any later version.
013     *
014     * JBoss DNA is distributed in the hope that it will be useful,
015     * but WITHOUT ANY WARRANTY; without even the implied warranty of
016     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
017     * Lesser General Public License for more details.
018     *
019     * You should have received a copy of the GNU Lesser General Public
020     * License along with this software; if not, write to the Free
021     * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
022     * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
023     */
024    package org.jboss.dna.common.math;
025    
026    import java.math.BigDecimal;
027    import java.util.Comparator;
028    import java.util.Random;
029    
030    public class IntegerOperations implements MathOperations<Integer>, Comparator<Integer> {
031    
032        public Class<Integer> getOperandClass() {
033            return Integer.class;
034        }
035    
036        public Integer add( Integer value1, Integer value2 ) {
037            if (value1 == null) return value2 != null ? value2 : createZeroValue();
038            if (value2 == null) return value1;
039            return value1 + value2;
040        }
041    
042        public Integer subtract( Integer value1, Integer value2 ) {
043            if (value1 == null) return negate(value2);
044            if (value2 == null) return value1;
045            return value1 - value2;
046        }
047    
048        public Integer multiply( Integer value1, Integer value2 ) {
049            if (value1 == null || value2 == null) return createZeroValue();
050            return value1 * value2;
051        }
052    
053        public double divide( Integer value1, Integer value2 ) {
054            if (value1 == null || value2 == null) throw new IllegalArgumentException();
055            return value1 / value2;
056        }
057    
058        public Integer negate( Integer value ) {
059            if (value == null) return createZeroValue();
060            return value * -1;
061        }
062    
063        public Integer increment( Integer value ) {
064            if (value == null) return createZeroValue();
065            return value + 1;
066        }
067    
068        public Integer maximum( Integer value1, Integer value2 ) {
069            if (value1 == null) return value2;
070            if (value2 == null) return value1;
071            return Math.max(value1, value2);
072        }
073    
074        public Integer minimum( Integer value1, Integer value2 ) {
075            if (value1 == null) return value2;
076            if (value2 == null) return value1;
077            return Math.min(value1, value2);
078        }
079    
080        public int compare( Integer value1, Integer value2 ) {
081            if (value1 == null) return value2 != null ? -1 : 0;
082            if (value2 == null) return 1;
083            return value1.compareTo(value2);
084        }
085    
086        public BigDecimal asBigDecimal( Integer value ) {
087            return value != null ? new BigDecimal(value) : null;
088        }
089    
090        public Integer fromBigDecimal( BigDecimal value ) {
091            return value != null ? value.intValue() : null;
092        }
093    
094        public Integer createZeroValue() {
095            return 0;
096        }
097    
098        public Integer create( int value ) {
099            return value;
100        }
101    
102        public Integer create( long value ) {
103            return (int)value;
104        }
105    
106        public Integer create( double value ) {
107            return (int)value;
108        }
109    
110        public double sqrt( Integer value ) {
111            return Math.sqrt(value);
112        }
113    
114        public Comparator<Integer> getComparator() {
115            return this;
116        }
117    
118        public Integer random( Integer minimum, Integer maximum, Random rng ) {
119            Integer difference = subtract(maximum, minimum);
120            return minimum + rng.nextInt(difference);
121        }
122    
123        public double doubleValue( Integer value ) {
124            return value.doubleValue();
125        }
126    
127        public float floatValue( Integer value ) {
128            return value.floatValue();
129        }
130    
131        public int intValue( Integer value ) {
132            return value.intValue();
133        }
134    
135        public long longValue( Integer value ) {
136            return value.longValue();
137        }
138    
139        public short shortValue( Integer value ) {
140            return value.shortValue();
141        }
142    
143        public int getExponentInScientificNotation( Integer value ) {
144            int v = Math.abs(value);
145            int exp = 0;
146            if (v > 1) {
147                while (v >= 10) {
148                    v /= 10;
149                    ++exp;
150                }
151            }
152            return exp;
153        }
154    
155        public Integer roundUp( Integer value, int decimalShift ) {
156            if (value == 0) return 0;
157            if (decimalShift >= 0) return value;
158            int shiftedValueP5 = Math.abs(value);
159            for (int i = 0; i != (-decimalShift - 1); ++i)
160                shiftedValueP5 /= 10;
161            shiftedValueP5 += 5l;
162            int shiftedValue = shiftedValueP5 / 10;
163            if (shiftedValue * 10l - shiftedValueP5 >= 5) ++shiftedValue;
164            shiftedValue *= Long.signum(value);
165            for (int i = 0; i != -decimalShift; ++i)
166                shiftedValue *= 10;
167            return shiftedValue;
168        }
169    
170        public Integer roundDown( Integer value, int decimalShift ) {
171            if (value == 0) return 0;
172            if (decimalShift >= 0) return value;
173            int shiftedValue = Math.abs(value);
174            for (int i = 0; i != -decimalShift; ++i)
175                shiftedValue /= 10;
176            shiftedValue *= Long.signum(value);
177            for (int i = 0; i != -decimalShift; ++i)
178                shiftedValue *= 10;
179            return shiftedValue;
180        }
181    
182        public Integer keepSignificantFigures( Integer value, int numSigFigs ) {
183            if (numSigFigs < 0) return value;
184            if (numSigFigs == 0) return 0;
185            int currentExp = getExponentInScientificNotation(value);
186            int decimalShift = -currentExp + numSigFigs - 1;
187            return roundUp(value, decimalShift);
188        }
189    }