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