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 ShortOperations implements MathOperations<Short>, Comparator<Short> {
031    
032        public Class<Short> getOperandClass() {
033            return Short.class;
034        }
035    
036        public Short add( Short value1, 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        public Short subtract( Short value1, Short value2 ) {
043            if (value1 == null) return negate(value2);
044            if (value2 == null) return value1;
045            return (short)(value1 - value2);
046        }
047    
048        public Short multiply( Short value1, Short value2 ) {
049            if (value1 == null || value2 == null) return createZeroValue();
050            return (short)(value1 * value2);
051        }
052    
053        public double divide( Short value1, Short value2 ) {
054            if (value1 == null || value2 == null) throw new IllegalArgumentException();
055            return value1 / value2;
056        }
057    
058        public Short negate( Short value ) {
059            if (value == null) return createZeroValue();
060            return (short)(value * -1);
061        }
062    
063        public Short increment( Short value ) {
064            if (value == null) return createZeroValue();
065            return (short)(value + 1);
066        }
067    
068        public Short maximum( Short value1, Short value2 ) {
069            if (value1 == null) return value2;
070            if (value2 == null) return value1;
071            return (short)Math.max(value1, value2);
072        }
073    
074        public Short minimum( Short value1, Short value2 ) {
075            if (value1 == null) return value2;
076            if (value2 == null) return value1;
077            return (short)Math.min(value1, value2);
078        }
079    
080        public int compare( Short value1, Short 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( Short value ) {
087            return value != null ? new BigDecimal(value) : null;
088        }
089    
090        public Short fromBigDecimal( BigDecimal value ) {
091            return value != null ? value.shortValue() : null;
092        }
093    
094        public Short createZeroValue() {
095            return 0;
096        }
097    
098        public Short create( int value ) {
099            return (short)value;
100        }
101    
102        public Short create( long value ) {
103            return (short)value;
104        }
105    
106        public Short create( double value ) {
107            return (short)value;
108        }
109    
110        public double sqrt( Short value ) {
111            return Math.sqrt(value);
112        }
113    
114        public Comparator<Short> getComparator() {
115            return this;
116        }
117    
118        public Short random( Short minimum, Short maximum, Random rng ) {
119            Short difference = subtract(maximum, minimum);
120            int increment = rng.nextInt(difference.intValue());
121            return new Integer(minimum + increment).shortValue();
122        }
123    
124        public double doubleValue( Short value ) {
125            return value.doubleValue();
126        }
127    
128        public float floatValue( Short value ) {
129            return value.floatValue();
130        }
131    
132        public int intValue( Short value ) {
133            return value.intValue();
134        }
135    
136        public long longValue( Short value ) {
137            return value.longValue();
138        }
139    
140        public short shortValue( Short value ) {
141            return value.shortValue();
142        }
143    
144        public int getExponentInScientificNotation( Short value ) {
145            int v = Math.abs(value);
146            int exp = 0;
147            if (v > 1) {
148                while (v >= 10) {
149                    v /= 10;
150                    ++exp;
151                }
152            } else if (v < 1) {
153                while (v < 1) {
154                    v *= 10;
155                    --exp;
156                }
157            }
158            return exp;
159        }
160    
161        public Short roundUp( Short value, int decimalShift ) {
162            if (value == 0) return 0;
163            if (decimalShift >= 0) return value;
164            int shiftedValueP5 = Math.abs(value);
165            for (int i = 0; i != (-decimalShift - 1); ++i)
166                shiftedValueP5 /= 10;
167            shiftedValueP5 += 5l;
168            int shiftedValue = shiftedValueP5 / 10;
169            if (shiftedValue * 10l - shiftedValueP5 >= 5) ++shiftedValue;
170            shiftedValue *= Long.signum(value);
171            for (int i = 0; i != -decimalShift; ++i)
172                shiftedValue *= 10;
173            return (short)shiftedValue;
174        }
175    
176        public Short roundDown( Short value, int decimalShift ) {
177            if (value == 0) return 0;
178            if (decimalShift >= 0) return value;
179            int shiftedValue = Math.abs(value);
180            for (int i = 0; i != -decimalShift; ++i)
181                shiftedValue /= 10;
182            shiftedValue *= Long.signum(value);
183            for (int i = 0; i != -decimalShift; ++i)
184                shiftedValue *= 10;
185            return (short)shiftedValue;
186        }
187    
188        public Short keepSignificantFigures( Short value, int numSigFigs ) {
189            if (numSigFigs < 0) return value;
190            if (numSigFigs == 0) return 0;
191            int currentExp = getExponentInScientificNotation(value);
192            int decimalShift = -currentExp + numSigFigs - 1;
193            return roundUp(value, decimalShift);
194        }
195    }