001/* 002 * ModeShape (http://www.modeshape.org) 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.modeshape.common.math; 017 018import java.math.BigDecimal; 019import java.util.Comparator; 020import java.util.Random; 021import org.modeshape.common.annotation.Immutable; 022 023/** 024 * The {@link MathOperations math operations} for float numbers. 025 */ 026@Immutable 027public class FloatOperations implements MathOperations<Float>, Comparator<Float> { 028 029 @Override 030 public Class<Float> getOperandClass() { 031 return Float.class; 032 } 033 034 @Override 035 public Float add( Float value1, 036 Float value2 ) { 037 if (value1 == null) return value2 != null ? value2 : createZeroValue(); 038 if (value2 == null) return value1; 039 return (value1 + value2); 040 } 041 042 @Override 043 public Float subtract( Float value1, 044 Float value2 ) { 045 if (value1 == null) return negate(value2); 046 if (value2 == null) return value1; 047 return (value1 - value2); 048 } 049 050 @Override 051 public Float multiply( Float value1, 052 Float value2 ) { 053 if (value1 == null || value2 == null) return createZeroValue(); 054 return (value1 * value2); 055 } 056 057 @Override 058 public double divide( Float value1, 059 Float value2 ) { 060 if (value1 == null || value2 == null) throw new IllegalArgumentException(); 061 return value1 / value2; 062 } 063 064 @Override 065 public Float negate( Float value ) { 066 if (value == null) return createZeroValue(); 067 return (value * -1); 068 } 069 070 @Override 071 public Float increment( Float value ) { 072 if (value == null) return createZeroValue(); 073 return (value + 1); 074 } 075 076 @Override 077 public Float maximum( Float value1, 078 Float value2 ) { 079 if (value1 == null) return value2; 080 if (value2 == null) return value1; 081 return Math.max(value1, value2); 082 } 083 084 @Override 085 public Float minimum( Float value1, 086 Float value2 ) { 087 if (value1 == null) return value2; 088 if (value2 == null) return value1; 089 return Math.min(value1, value2); 090 } 091 092 @Override 093 public int compare( Float value1, 094 Float value2 ) { 095 if (value1 == null) return value2 != null ? -1 : 0; 096 if (value2 == null) return 1; 097 return value1.compareTo(value2); 098 } 099 100 @Override 101 public BigDecimal asBigDecimal( Float value ) { 102 return value != null ? new BigDecimal(value) : null; 103 } 104 105 @Override 106 public Float fromBigDecimal( BigDecimal value ) { 107 return value != null ? value.floatValue() : null; 108 } 109 110 @Override 111 public Float createZeroValue() { 112 return 0.0f; 113 } 114 115 @Override 116 public Float create( int value ) { 117 return (float)value; 118 } 119 120 @Override 121 public Float create( long value ) { 122 return (float)value; 123 } 124 125 @Override 126 public Float create( double value ) { 127 return (float)value; 128 } 129 130 @Override 131 public double sqrt( Float value ) { 132 return Math.sqrt(value); 133 } 134 135 @Override 136 public Comparator<Float> getComparator() { 137 return this; 138 } 139 140 @Override 141 public Float random( Float minimum, 142 Float maximum, 143 Random rng ) { 144 Float difference = subtract(maximum, minimum); 145 return minimum + difference.floatValue() * rng.nextFloat(); 146 } 147 148 @Override 149 public double doubleValue( Float value ) { 150 return value.doubleValue(); 151 } 152 153 @Override 154 public float floatValue( Float value ) { 155 return value.floatValue(); 156 } 157 158 @Override 159 public int intValue( Float value ) { 160 return value.intValue(); 161 } 162 163 @Override 164 public long longValue( Float value ) { 165 return value.longValue(); 166 } 167 168 @Override 169 public short shortValue( Float value ) { 170 return value.shortValue(); 171 } 172 173 @Override 174 public int getExponentInScientificNotation( Float value ) { 175 double v = Math.abs(value); 176 int exp = 0; 177 if (v > 1.0d) { 178 while (v >= 10.0d) { 179 v /= 10.0d; 180 ++exp; 181 } 182 } else if (v == 0.0d) { 183 } else if (v < 1.0d) { 184 while (v < 1.0d) { 185 v *= 10.0d; 186 --exp; 187 } 188 } 189 return exp; 190 } 191 192 @Override 193 public Float roundUp( Float value, 194 int decimalShift ) { 195 if (value == 0) return 0.0f; 196 double shiftedValue = (Math.abs(value.doubleValue()) * Math.pow(10.0d, decimalShift) + 0.5d) * Math.signum(value); 197 double roundedValue = (long)shiftedValue; 198 return (float)(roundedValue * Math.pow(10.0d, -decimalShift)); 199 } 200 201 @Override 202 public Float roundDown( Float value, 203 int decimalShift ) { 204 if (value == 0) return 0.0f; 205 if (decimalShift > 0) return value; 206 double shiftedValue = (Math.abs(value.doubleValue()) * Math.pow(10.0d, decimalShift)) * Math.signum(value); 207 double roundedValue = (long)shiftedValue; 208 return (float)(roundedValue * Math.pow(10.0d, -decimalShift)); 209 } 210 211 @Override 212 public Float keepSignificantFigures( Float value, 213 int numSigFigs ) { 214 int currentExp = getExponentInScientificNotation(value); 215 int decimalShift = (int)Math.signum(currentExp) * (Math.abs(currentExp) + numSigFigs - 1); 216 return roundUp(value, decimalShift); 217 } 218}