1 11 package org.eclipse.jdt.internal.compiler.util; 12 13 18 public class FloatUtil { 19 20 private static final int DOUBLE_FRACTION_WIDTH = 52; 21 22 private static final int DOUBLE_PRECISION = 53; 23 24 private static final int MAX_DOUBLE_EXPONENT = +1023; 25 26 private static final int MIN_NORMALIZED_DOUBLE_EXPONENT = -1022; 27 28 private static final int MIN_UNNORMALIZED_DOUBLE_EXPONENT = MIN_NORMALIZED_DOUBLE_EXPONENT 29 - DOUBLE_PRECISION; 30 31 private static final int DOUBLE_EXPONENT_BIAS = +1023; 32 33 private static final int DOUBLE_EXPONENT_SHIFT = 52; 34 35 private static final int SINGLE_FRACTION_WIDTH = 23; 36 37 private static final int SINGLE_PRECISION = 24; 38 39 private static final int MAX_SINGLE_EXPONENT = +127; 40 41 private static final int MIN_NORMALIZED_SINGLE_EXPONENT = -126; 42 43 private static final int MIN_UNNORMALIZED_SINGLE_EXPONENT = MIN_NORMALIZED_SINGLE_EXPONENT 44 - SINGLE_PRECISION; 45 46 private static final int SINGLE_EXPONENT_BIAS = +127; 47 48 private static final int SINGLE_EXPONENT_SHIFT = 23; 49 50 72 public static float valueOfHexFloatLiteral(char[] source) { 73 long bits = convertHexFloatingPointLiteralToBits(source); 74 return Float.intBitsToFloat((int) bits); 75 } 76 77 99 public static double valueOfHexDoubleLiteral(char[] source) { 100 long bits = convertHexFloatingPointLiteralToBits(source); 101 return Double.longBitsToDouble(bits); 102 } 103 104 118 private static long convertHexFloatingPointLiteralToBits(char[] source) { 119 int length = source.length; 120 long mantissa = 0; 121 122 int next = 0; 124 char nextChar = source[next]; 125 nextChar = source[next]; 126 if (nextChar == '0') { 127 next++; 128 } else { 129 throw new NumberFormatException (); 130 } 131 nextChar = source[next]; 132 if (nextChar == 'X' || nextChar == 'x') { 133 next++; 134 } else { 135 throw new NumberFormatException (); 136 } 137 138 int binaryPointPosition = -1; 140 loop: while (true) { 141 nextChar = source[next]; 142 switch (nextChar) { 143 case '0': 144 next++; 145 continue loop; 146 case '.': 147 binaryPointPosition = next; 148 next++; 149 continue loop; 150 default: 151 break loop; 152 } 153 } 154 155 int mantissaBits = 0; 158 int leadingDigitPosition = -1; 159 loop: while (true) { 160 nextChar = source[next]; 161 int hexdigit; 162 switch (nextChar) { 163 case '0': 164 case '1': 165 case '2': 166 case '3': 167 case '4': 168 case '5': 169 case '6': 170 case '7': 171 case '8': 172 case '9': 173 hexdigit = nextChar - '0'; 174 break; 175 case 'a': 176 case 'b': 177 case 'c': 178 case 'd': 179 case 'e': 180 case 'f': 181 hexdigit = (nextChar - 'a') + 10; 182 break; 183 case 'A': 184 case 'B': 185 case 'C': 186 case 'D': 187 case 'E': 188 case 'F': 189 hexdigit = (nextChar - 'A') + 10; 190 break; 191 case '.': 192 binaryPointPosition = next; 193 next++; 194 continue loop; 195 default: 196 if (binaryPointPosition < 0) { 197 binaryPointPosition = next; 199 } 200 break loop; 201 } 202 if (mantissaBits == 0) { 203 leadingDigitPosition = next; 206 mantissa = hexdigit; 207 mantissaBits = 4; 208 } else if (mantissaBits < 60) { 209 mantissa <<= 4; 211 mantissa |= hexdigit; 212 mantissaBits += 4; 213 } else { 214 } 217 next++; 218 continue loop; 219 } 220 221 nextChar = source[next]; 223 if (nextChar == 'P' || nextChar == 'p') { 224 next++; 225 } else { 226 throw new NumberFormatException (); 227 } 228 229 int exponent = 0; 231 int exponentSign = +1; 232 loop: while (next < length) { 233 nextChar = source[next]; 234 switch (nextChar) { 235 case '+': 236 exponentSign = +1; 237 next++; 238 continue loop; 239 case '-': 240 exponentSign = -1; 241 next++; 242 continue loop; 243 case '0': 244 case '1': 245 case '2': 246 case '3': 247 case '4': 248 case '5': 249 case '6': 250 case '7': 251 case '8': 252 case '9': 253 int digit = nextChar - '0'; 254 exponent = (exponent * 10) + digit; 255 next++; 256 continue loop; 257 default: 258 break loop; 259 } 260 } 261 262 boolean doublePrecision = true; 264 if (next < length) { 265 nextChar = source[next]; 266 switch (nextChar) { 267 case 'f': 268 case 'F': 269 doublePrecision = false; 270 next++; 271 break; 272 case 'd': 273 case 'D': 274 doublePrecision = true; 275 next++; 276 break; 277 default: 278 throw new NumberFormatException (); 279 } 280 } 281 282 if (mantissa == 0) { 285 return 0L; 286 } 287 288 int scaleFactorCompensation = 0; 292 long top = (mantissa >>> (mantissaBits - 4)); 293 if ((top & 0x8) == 0) { 294 mantissaBits--; 295 scaleFactorCompensation++; 296 if ((top & 0x4) == 0) { 297 mantissaBits--; 298 scaleFactorCompensation++; 299 if ((top & 0x2) == 0) { 300 mantissaBits--; 301 scaleFactorCompensation++; 302 } 303 } 304 } 305 306 long result = 0L; 308 if (doublePrecision) { 309 long fraction; 310 if (mantissaBits > DOUBLE_PRECISION) { 311 int extraBits = mantissaBits - DOUBLE_PRECISION; 313 fraction = mantissa >>> (extraBits - 1); 315 long lowBit = fraction & 0x1; 316 fraction += lowBit; 317 fraction = fraction >>> 1; 318 if ((fraction & (1L << DOUBLE_PRECISION)) != 0) { 319 fraction = fraction >>> 1; 320 scaleFactorCompensation -= 1; 321 } 322 } else { 323 fraction = mantissa << (DOUBLE_PRECISION - mantissaBits); 325 } 326 327 int scaleFactor = 0; if (mantissaBits > 0) { 329 if (leadingDigitPosition < binaryPointPosition) { 330 scaleFactor = 4 * (binaryPointPosition - leadingDigitPosition); 332 scaleFactor -= scaleFactorCompensation; 334 } else { 335 scaleFactor = -4 337 * (leadingDigitPosition - binaryPointPosition - 1); 338 scaleFactor -= scaleFactorCompensation; 340 } 341 } 342 343 int e = (exponentSign * exponent) + scaleFactor; 344 if (e - 1 > MAX_DOUBLE_EXPONENT) { 345 result = Double.doubleToLongBits(Double.POSITIVE_INFINITY); 347 } else if (e - 1 >= MIN_NORMALIZED_DOUBLE_EXPONENT) { 348 long biasedExponent = e - 1 + DOUBLE_EXPONENT_BIAS; 351 result = fraction & ~(1L << DOUBLE_FRACTION_WIDTH); 352 result |= (biasedExponent << DOUBLE_EXPONENT_SHIFT); 353 } else if (e - 1 > MIN_UNNORMALIZED_DOUBLE_EXPONENT) { 354 long biasedExponent = 0; 356 result = fraction >>> (MIN_NORMALIZED_DOUBLE_EXPONENT - e + 1); 357 result |= (biasedExponent << DOUBLE_EXPONENT_SHIFT); 358 } else { 359 result = Double.doubleToLongBits(Double.NaN); 361 } 362 return result; 363 } 364 365 long fraction; 367 if (mantissaBits > SINGLE_PRECISION) { 368 int extraBits = mantissaBits - SINGLE_PRECISION; 370 fraction = mantissa >>> (extraBits - 1); 372 long lowBit = fraction & 0x1; 373 fraction += lowBit; 374 fraction = fraction >>> 1; 375 if ((fraction & (1L << SINGLE_PRECISION)) != 0) { 376 fraction = fraction >>> 1; 377 scaleFactorCompensation -= 1; 378 } 379 } else { 380 fraction = mantissa << (SINGLE_PRECISION - mantissaBits); 382 } 383 384 int scaleFactor = 0; if (mantissaBits > 0) { 386 if (leadingDigitPosition < binaryPointPosition) { 387 scaleFactor = 4 * (binaryPointPosition - leadingDigitPosition); 389 scaleFactor -= scaleFactorCompensation; 391 } else { 392 scaleFactor = -4 394 * (leadingDigitPosition - binaryPointPosition - 1); 395 scaleFactor -= scaleFactorCompensation; 397 } 398 } 399 400 int e = (exponentSign * exponent) + scaleFactor; 401 if (e - 1 > MAX_SINGLE_EXPONENT) { 402 result = Float.floatToIntBits(Float.POSITIVE_INFINITY); 404 } else if (e - 1 >= MIN_NORMALIZED_SINGLE_EXPONENT) { 405 long biasedExponent = e - 1 + SINGLE_EXPONENT_BIAS; 408 result = fraction & ~(1L << SINGLE_FRACTION_WIDTH); 409 result |= (biasedExponent << SINGLE_EXPONENT_SHIFT); 410 } else if (e - 1 > MIN_UNNORMALIZED_SINGLE_EXPONENT) { 411 long biasedExponent = 0; 413 result = fraction >>> (MIN_NORMALIZED_SINGLE_EXPONENT - e + 1); 414 result |= (biasedExponent << SINGLE_EXPONENT_SHIFT); 415 } else { 416 result = Float.floatToIntBits(Float.NaN); 418 } 419 return result; 420 } 421 } 422 | Popular Tags |