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