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