<s> package org . eclipse . jdt . internal . compiler . util ; public class FloatUtil { private static final int DOUBLE_FRACTION_WIDTH = 52 ; private static final int DOUBLE_PRECISION = 53 ; private static final int MAX_DOUBLE_EXPONENT = + 1023 ; private static final int MIN_NORMALIZED_DOUBLE_EXPONENT = - 1022 ; private static final int MIN_UNNORMALIZED_DOUBLE_EXPONENT = MIN_NORMALIZED_DOUBLE_EXPONENT - DOUBLE_PRECISION ; private static final int DOUBLE_EXPONENT_BIAS = + 1023 ; private static final int DOUBLE_EXPONENT_SHIFT = 52 ; private static final int SINGLE_FRACTION_WIDTH = 23 ; private static final int SINGLE_PRECISION = 24 ; private static final int MAX_SINGLE_EXPONENT = + 127 ; private static final int MIN_NORMALIZED_SINGLE_EXPONENT = - 126 ; private static final int MIN_UNNORMALIZED_SINGLE_EXPONENT = MIN_NORMALIZED_SINGLE_EXPONENT - SINGLE_PRECISION ; private static final int SINGLE_EXPONENT_BIAS = + 127 ; private static final int SINGLE_EXPONENT_SHIFT = 23 ; public static float valueOfHexFloatLiteral ( char [ ] source ) { long bits = convertHexFloatingPointLiteralToBits ( source ) ; return Float . intBitsToFloat ( ( int ) bits ) ; } public static double valueOfHexDoubleLiteral ( char [ ] source ) { long bits = convertHexFloatingPointLiteralToBits ( source ) ; return Double . longBitsToDouble ( bits ) ; } private static long convertHexFloatingPointLiteralToBits ( char [ ] source ) { int length = source . length ; long mantissa = 0 ; int next = 0 ; char nextChar = source [ next ] ; nextChar = source [ next ] ; if ( nextChar == '0' ) { next ++ ; } else { throw new NumberFormatException ( ) ; } nextChar = source [ next ] ; if ( nextChar == 'X' || nextChar == 'x' ) { next ++ ; } else { throw new NumberFormatException ( ) ; } int binaryPointPosition = - 1 ; loop : while ( true ) { nextChar = source [ next ] ; switch ( nextChar ) { case '0' : next ++ ; continue loop ; case '.' : binaryPointPosition = next ; next ++ ; continue loop ; default : break loop ; } } int mantissaBits = 0 ; int leadingDigitPosition = - 1 ; loop : while ( true ) { nextChar = source [ next ] ; int hexdigit ; switch ( nextChar ) { case '0' : case '1' : case '2' : case '3' : case '4' : case '5' : case '6' : case '7' : case '8' : case '9' : hexdigit = nextChar - '0' ; break ; case 'a' : case 'b' : case 'c' : case 'd' : case 'e' : case 'f' : hexdigit = ( nextChar - 'a' ) + 10 ; break ; case 'A' : case 'B' : case 'C' : case 'D' : case 'E' : case 'F' : hexdigit = ( nextChar - 'A' ) + 10 ; break ; case '.' : binaryPointPosition = next ; next ++ ; continue loop ; default : if ( binaryPointPosition < 0 ) { binaryPointPosition = next ; } break loop ; } if ( mantissaBits == 0 ) { leadingDigitPosition = next ; mantissa = hexdigit ; mantissaBits = 4 ; } else if ( mantissaBits < 60 ) { mantissa <<= 4 ; mantissa |= hexdigit ; mantissaBits += 4 ; } else { } next ++ ; continue loop ; } nextChar = source [ next ] ; if ( nextChar == 'P' || nextChar == 'p' ) { next ++ ; } else { throw new NumberFormatException ( ) ; } int exponent = 0 ; int exponentSign = + 1 ; loop : while ( next < length ) { nextChar = source [ next ] ; switch ( nextChar ) { case '+' : exponentSign = + 1 ; next ++ ; continue loop ; case '-' : exponentSign = - 1 ; next ++ ; continue loop ; case '0' : case '1' : case '2' : case '3' : case '4' : case '5' : case '6' : case '7' : case '8' : case '9' : int digit = nextChar - '0' ; exponent = ( exponent * 10 ) + digit ; next ++ ; continue loop ; default : break loop ; } } boolean doublePrecision = true ; if ( next < length ) { nextChar = source [ next ] ; switch ( nextChar ) { case 'f' : case 'F' : doublePrecision = false ; next ++ ; break ; case 'd' : case 'D' : doublePrecision = true ; next ++ ; break ; default : throw new NumberFormatException ( ) ; } } if ( mantissa == 0 ) { return 0L ; } int scaleFactorCompensation = 0 ; long top = ( mantissa >>> ( mantissaBits - 4 ) ) ; if ( ( top & 0x8 ) == 0 ) { mantissaBits -- ; scaleFactorCompensation ++ ; if ( ( top & 0x4 ) == 0 ) { mantissaBits -- ; scaleFactorCompensation ++ ; if ( ( top & 0x2 ) == 0 ) { mantissaBits -- ; scaleFactorCompensation ++ ; } } } long result = 0L ; if ( doublePrecision ) { long fraction ; if ( mantissaBits > DOUBLE_PRECISION ) { int extraBits = mantissaBits - DOUBLE_PRECISION ; fraction = mantissa >>> ( extraBits - 1 ) ; long lowBit = fraction & 0x1 ; fraction += lowBit ; fraction = fraction >>> 1 ; if ( ( fraction & ( 1L << DOUBLE_PRECISION ) ) != 0 ) { fraction = fraction >>> 1 ; scaleFactorCompensation -= 1 ; } } else { fraction = mantissa << ( DOUBLE_PRECISION - mantissaBits ) ; } int scaleFactor = 0 ; if ( mantissaBits > 0 ) { if ( leadingDigitPosition < binaryPointPosition ) { scaleFactor = 4 * ( binaryPointPosition - leadingDigitPosition ) ; scaleFactor -= scaleFactorCompensation ; } else { scaleFactor = - 4 * ( leadingDigitPosition - binaryPointPosition - 1 ) ; scaleFactor -= scaleFactorCompensation ; } } int e = ( exponentSign * exponent ) + scaleFactor ; if ( e - 1 > MAX_DOUBLE_EXPONENT ) { result = Double . doubleToLongBits ( Double . POSITIVE_INFINITY ) ; } else if ( e - 1 >= MIN_NORMALIZED_DOUBLE_EXPONENT ) { long biasedExponent = e - 1 + DOUBLE_EXPONENT_BIAS ; result = fraction & ~ ( 1L << DOUBLE_FRACTION_WIDTH ) ; result |= ( biasedExponent << DOUBLE_EXPONENT_SHIFT ) ; } else if ( e - 1 > MIN_UNNORMALIZED_DOUBLE_EXPONENT ) { long biasedExponent = 0 ; result = fraction >>> ( MIN_NORMALIZED_DOUBLE_EXPONENT - e + 1 ) ; result |= ( biasedExponent << DOUBLE_EXPONENT_SHIFT ) ; } else { result = Double . doubleToLongBits ( Double . NaN ) ; } return result ; } long fraction ; if ( mantissaBits > SINGLE_PRECISION ) { int extraBits = mantissaBits - SINGLE_PRECISION ; fraction = mantissa >>> ( extraBits - 1 ) ; long lowBit = fraction & 0x1 ; fraction += lowBit ; fraction = fraction >>> 1 ; if ( ( fraction & ( 1L << SINGLE_PRECISION ) ) != 0 ) { fraction = fraction >>> 1 ; scaleFactorCompensation -= 1 ; } } else { fraction = mantissa << ( SINGLE_PRECISION - mantissaBits ) ; } int scaleFactor = 0 ; if ( mantissaBits > 0 ) { if ( leadingDigitPosition < binaryPointPosition ) { scaleFactor = 4 * ( binaryPointPosition - leadingDigitPosition ) ; scaleFactor -= scaleFactorCompensation ; } else { scaleFactor = - 4 * ( leadingDigitPosition - binaryPointPosition - 1 ) ; scaleFactor -= scaleFactorCompensation ; } } int e = ( exponentSign * exponent ) + scaleFactor ; if ( e - 1 > MAX_SINGLE_EXPONENT ) { result = Float . floatToIntBits ( Float . POSITIVE_INFINITY ) ; } else if ( e - 1 >= MIN_NORMALIZED_SINGLE_EXPONENT ) { long biasedExponent = e - 1 + SINGLE_EXPONENT_BIAS ; result = fraction & ~ ( 1L << SINGLE_FRACTION_WIDTH ) ; result |= ( biasedExponent << SINGLE_EXPONENT_SHIFT ) ; } else if ( e - 1 > MIN_UNNORMALIZED_SINGLE_EXPONENT ) { long biasedExponent = 0 ; result = fraction >>> ( MIN_NORMALIZED_SINGLE_EXPONENT - e + 1 ) ; result |= ( biasedExponent << SINGLE_EXPONENT_SHIFT ) ; } else { result = Float . floatToIntBits ( Float . NaN ) ; } return result ; } } </s>