--- a/jdk/src/share/classes/sun/misc/FormattedFloatingDecimal.java Thu Mar 12 10:27:22 2009 -0700
+++ b/jdk/src/share/classes/sun/misc/FormattedFloatingDecimal.java Thu Mar 12 10:32:58 2009 -0700
@@ -978,15 +978,6 @@
return new String(result);
}
- // This method should only ever be called if this object is constructed
- // without Form.DECIMAL_FLOAT because the perThreadBuffer is not large
- // enough to handle floating-point numbers of large precision.
- public String toJavaFormatString() {
- char result[] = (char[])(perThreadBuffer.get());
- int i = getChars(result);
- return new String(result, 0, i);
- }
-
// returns the exponent before rounding
public int getExponent() {
return decExponent - 1;
@@ -1157,265 +1148,6 @@
}
};
- // This method should only ever be called if this object is constructed
- // without Form.DECIMAL_FLOAT because the perThreadBuffer is not large
- // enough to handle floating-point numbers of large precision.
- public void appendTo(Appendable buf) {
- char result[] = (char[])(perThreadBuffer.get());
- int i = getChars(result);
- if (buf instanceof StringBuilder)
- ((StringBuilder) buf).append(result, 0, i);
- else if (buf instanceof StringBuffer)
- ((StringBuffer) buf).append(result, 0, i);
- else
- assert false;
- }
-
- public static FormattedFloatingDecimal
- readJavaFormatString( String in ) throws NumberFormatException {
- boolean isNegative = false;
- boolean signSeen = false;
- int decExp;
- char c;
-
- parseNumber:
- try{
- in = in.trim(); // don't fool around with white space.
- // throws NullPointerException if null
- int l = in.length();
- if ( l == 0 ) throw new NumberFormatException("empty String");
- int i = 0;
- switch ( c = in.charAt( i ) ){
- case '-':
- isNegative = true;
- //FALLTHROUGH
- case '+':
- i++;
- signSeen = true;
- }
-
- // Check for NaN and Infinity strings
- c = in.charAt(i);
- if(c == 'N' || c == 'I') { // possible NaN or infinity
- boolean potentialNaN = false;
- char targetChars[] = null; // char arrary of "NaN" or "Infinity"
-
- if(c == 'N') {
- targetChars = notANumber;
- potentialNaN = true;
- } else {
- targetChars = infinity;
- }
-
- // compare Input string to "NaN" or "Infinity"
- int j = 0;
- while(i < l && j < targetChars.length) {
- if(in.charAt(i) == targetChars[j]) {
- i++; j++;
- }
- else // something is amiss, throw exception
- break parseNumber;
- }
-
- // For the candidate string to be a NaN or infinity,
- // all characters in input string and target char[]
- // must be matched ==> j must equal targetChars.length
- // and i must equal l
- if( (j == targetChars.length) && (i == l) ) { // return NaN or infinity
- return (potentialNaN ? new FormattedFloatingDecimal(Double.NaN) // NaN has no sign
- : new FormattedFloatingDecimal(isNegative?
- Double.NEGATIVE_INFINITY:
- Double.POSITIVE_INFINITY)) ;
- }
- else { // something went wrong, throw exception
- break parseNumber;
- }
-
- } else if (c == '0') { // check for hexadecimal floating-point number
- if (l > i+1 ) {
- char ch = in.charAt(i+1);
- if (ch == 'x' || ch == 'X' ) // possible hex string
- return parseHexString(in);
- }
- } // look for and process decimal floating-point string
-
- char[] digits = new char[ l ];
- int nDigits= 0;
- boolean decSeen = false;
- int decPt = 0;
- int nLeadZero = 0;
- int nTrailZero= 0;
- digitLoop:
- while ( i < l ){
- switch ( c = in.charAt( i ) ){
- case '0':
- if ( nDigits > 0 ){
- nTrailZero += 1;
- } else {
- nLeadZero += 1;
- }
- break; // out of switch.
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- while ( nTrailZero > 0 ){
- digits[nDigits++] = '0';
- nTrailZero -= 1;
- }
- digits[nDigits++] = c;
- break; // out of switch.
- case '.':
- if ( decSeen ){
- // already saw one ., this is the 2nd.
- throw new NumberFormatException("multiple points");
- }
- decPt = i;
- if ( signSeen ){
- decPt -= 1;
- }
- decSeen = true;
- break; // out of switch.
- default:
- break digitLoop;
- }
- i++;
- }
- /*
- * At this point, we've scanned all the digits and decimal
- * point we're going to see. Trim off leading and trailing
- * zeros, which will just confuse us later, and adjust
- * our initial decimal exponent accordingly.
- * To review:
- * we have seen i total characters.
- * nLeadZero of them were zeros before any other digits.
- * nTrailZero of them were zeros after any other digits.
- * if ( decSeen ), then a . was seen after decPt characters
- * ( including leading zeros which have been discarded )
- * nDigits characters were neither lead nor trailing
- * zeros, nor point
- */
- /*
- * special hack: if we saw no non-zero digits, then the
- * answer is zero!
- * Unfortunately, we feel honor-bound to keep parsing!
- */
- if ( nDigits == 0 ){
- digits = zero;
- nDigits = 1;
- if ( nLeadZero == 0 ){
- // we saw NO DIGITS AT ALL,
- // not even a crummy 0!
- // this is not allowed.
- break parseNumber; // go throw exception
- }
-
- }
-
- /* Our initial exponent is decPt, adjusted by the number of
- * discarded zeros. Or, if there was no decPt,
- * then its just nDigits adjusted by discarded trailing zeros.
- */
- if ( decSeen ){
- decExp = decPt - nLeadZero;
- } else {
- decExp = nDigits+nTrailZero;
- }
-
- /*
- * Look for 'e' or 'E' and an optionally signed integer.
- */
- if ( (i < l) && (((c = in.charAt(i) )=='e') || (c == 'E') ) ){
- int expSign = 1;
- int expVal = 0;
- int reallyBig = Integer.MAX_VALUE / 10;
- boolean expOverflow = false;
- switch( in.charAt(++i) ){
- case '-':
- expSign = -1;
- //FALLTHROUGH
- case '+':
- i++;
- }
- int expAt = i;
- expLoop:
- while ( i < l ){
- if ( expVal >= reallyBig ){
- // the next character will cause integer
- // overflow.
- expOverflow = true;
- }
- switch ( c = in.charAt(i++) ){
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- expVal = expVal*10 + ( (int)c - (int)'0' );
- continue;
- default:
- i--; // back up.
- break expLoop; // stop parsing exponent.
- }
- }
- int expLimit = bigDecimalExponent+nDigits+nTrailZero;
- if ( expOverflow || ( expVal > expLimit ) ){
- //
- // The intent here is to end up with
- // infinity or zero, as appropriate.
- // The reason for yielding such a small decExponent,
- // rather than something intuitive such as
- // expSign*Integer.MAX_VALUE, is that this value
- // is subject to further manipulation in
- // doubleValue() and floatValue(), and I don't want
- // it to be able to cause overflow there!
- // (The only way we can get into trouble here is for
- // really outrageous nDigits+nTrailZero, such as 2 billion. )
- //
- decExp = expSign*expLimit;
- } else {
- // this should not overflow, since we tested
- // for expVal > (MAX+N), where N >= abs(decExp)
- decExp = decExp + expSign*expVal;
- }
-
- // if we saw something not a digit ( or end of string )
- // after the [Ee][+-], without seeing any digits at all
- // this is certainly an error. If we saw some digits,
- // but then some trailing garbage, that might be ok.
- // so we just fall through in that case.
- // HUMBUG
- if ( i == expAt )
- break parseNumber; // certainly bad
- }
- /*
- * We parsed everything we could.
- * If there are leftovers, then this is not good input!
- */
- if ( i < l &&
- ((i != l - 1) ||
- (in.charAt(i) != 'f' &&
- in.charAt(i) != 'F' &&
- in.charAt(i) != 'd' &&
- in.charAt(i) != 'D'))) {
- break parseNumber; // go throw exception
- }
-
- return new FormattedFloatingDecimal( isNegative, decExp, digits, nDigits, false, Integer.MAX_VALUE, Form.COMPATIBLE );
- } catch ( StringIndexOutOfBoundsException e ){ }
- throw new NumberFormatException("For input string: \"" + in + "\"");
- }
-
/*
* Take a FormattedFloatingDecimal, which we presumably just scanned in,
* and find out what its value is, as a double.
@@ -2035,548 +1767,4 @@
private static final char infinity[] = { 'I', 'n', 'f', 'i', 'n', 'i', 't', 'y' };
private static final char notANumber[] = { 'N', 'a', 'N' };
private static final char zero[] = { '0', '0', '0', '0', '0', '0', '0', '0' };
-
-
- /*
- * Grammar is compatible with hexadecimal floating-point constants
- * described in section 6.4.4.2 of the C99 specification.
- */
- private static Pattern hexFloatPattern = Pattern.compile(
- //1 234 56 7 8 9
- "([-+])?0[xX](((\\p{XDigit}+)\\.?)|((\\p{XDigit}*)\\.(\\p{XDigit}+)))[pP]([-+])?(\\p{Digit}+)[fFdD]?"
- );
-
- /*
- * Convert string s to a suitable floating decimal; uses the
- * double constructor and set the roundDir variable appropriately
- * in case the value is later converted to a float.
- */
- static FormattedFloatingDecimal parseHexString(String s) {
- // Verify string is a member of the hexadecimal floating-point
- // string language.
- Matcher m = hexFloatPattern.matcher(s);
- boolean validInput = m.matches();
-
- if (!validInput) {
- // Input does not match pattern
- throw new NumberFormatException("For input string: \"" + s + "\"");
- } else { // validInput
- /*
- * We must isolate the sign, significand, and exponent
- * fields. The sign value is straightforward. Since
- * floating-point numbers are stored with a normalized
- * representation, the significand and exponent are
- * interrelated.
- *
- * After extracting the sign, we normalized the
- * significand as a hexadecimal value, calculating an
- * exponent adjust for any shifts made during
- * normalization. If the significand is zero, the
- * exponent doesn't need to be examined since the output
- * will be zero.
- *
- * Next the exponent in the input string is extracted.
- * Afterwards, the significand is normalized as a *binary*
- * value and the input value's normalized exponent can be
- * computed. The significand bits are copied into a
- * double significand; if the string has more logical bits
- * than can fit in a double, the extra bits affect the
- * round and sticky bits which are used to round the final
- * value.
- */
-
- // Extract significand sign
- String group1 = m.group(1);
- double sign = (( group1 == null ) || group1.equals("+"))? 1.0 : -1.0;
-
-
- // Extract Significand magnitude
- /*
- * Based on the form of the significand, calculate how the
- * binary exponent needs to be adjusted to create a
- * normalized *hexadecimal* floating-point number; that
- * is, a number where there is one nonzero hex digit to
- * the left of the (hexa)decimal point. Since we are
- * adjusting a binary, not hexadecimal exponent, the
- * exponent is adjusted by a multiple of 4.
- *
- * There are a number of significand scenarios to consider;
- * letters are used in indicate nonzero digits:
- *
- * 1. 000xxxx => x.xxx normalized
- * increase exponent by (number of x's - 1)*4
- *
- * 2. 000xxx.yyyy => x.xxyyyy normalized
- * increase exponent by (number of x's - 1)*4
- *
- * 3. .000yyy => y.yy normalized
- * decrease exponent by (number of zeros + 1)*4
- *
- * 4. 000.00000yyy => y.yy normalized
- * decrease exponent by (number of zeros to right of point + 1)*4
- *
- * If the significand is exactly zero, return a properly
- * signed zero.
- */
-
- String significandString =null;
- int signifLength = 0;
- int exponentAdjust = 0;
- {
- int leftDigits = 0; // number of meaningful digits to
- // left of "decimal" point
- // (leading zeros stripped)
- int rightDigits = 0; // number of digits to right of
- // "decimal" point; leading zeros
- // must always be accounted for
- /*
- * The significand is made up of either
- *
- * 1. group 4 entirely (integer portion only)
- *
- * OR
- *
- * 2. the fractional portion from group 7 plus any
- * (optional) integer portions from group 6.
- */
- String group4;
- if( (group4 = m.group(4)) != null) { // Integer-only significand
- // Leading zeros never matter on the integer portion
- significandString = stripLeadingZeros(group4);
- leftDigits = significandString.length();
- }
- else {
- // Group 6 is the optional integer; leading zeros
- // never matter on the integer portion
- String group6 = stripLeadingZeros(m.group(6));
- leftDigits = group6.length();
-
- // fraction
- String group7 = m.group(7);
- rightDigits = group7.length();
-
- // Turn "integer.fraction" into "integer"+"fraction"
- significandString =
- ((group6 == null)?"":group6) + // is the null
- // check necessary?
- group7;
- }
-
- significandString = stripLeadingZeros(significandString);
- signifLength = significandString.length();
-
- /*
- * Adjust exponent as described above
- */
- if (leftDigits >= 1) { // Cases 1 and 2
- exponentAdjust = 4*(leftDigits - 1);
- } else { // Cases 3 and 4
- exponentAdjust = -4*( rightDigits - signifLength + 1);
- }
-
- // If the significand is zero, the exponent doesn't
- // matter; return a properly signed zero.
-
- if (signifLength == 0) { // Only zeros in input
- return new FormattedFloatingDecimal(sign * 0.0);
- }
- }
-
- // Extract Exponent
- /*
- * Use an int to read in the exponent value; this should
- * provide more than sufficient range for non-contrived
- * inputs. If reading the exponent in as an int does
- * overflow, examine the sign of the exponent and
- * significand to determine what to do.
- */
- String group8 = m.group(8);
- boolean positiveExponent = ( group8 == null ) || group8.equals("+");
- long unsignedRawExponent;
- try {
- unsignedRawExponent = Integer.parseInt(m.group(9));
- }
- catch (NumberFormatException e) {
- // At this point, we know the exponent is
- // syntactically well-formed as a sequence of
- // digits. Therefore, if an NumberFormatException
- // is thrown, it must be due to overflowing int's
- // range. Also, at this point, we have already
- // checked for a zero significand. Thus the signs
- // of the exponent and significand determine the
- // final result:
- //
- // significand
- // + -
- // exponent + +infinity -infinity
- // - +0.0 -0.0
- return new FormattedFloatingDecimal(sign * (positiveExponent ?
- Double.POSITIVE_INFINITY : 0.0));
- }
-
- long rawExponent =
- (positiveExponent ? 1L : -1L) * // exponent sign
- unsignedRawExponent; // exponent magnitude
-
- // Calculate partially adjusted exponent
- long exponent = rawExponent + exponentAdjust ;
-
- // Starting copying non-zero bits into proper position in
- // a long; copy explicit bit too; this will be masked
- // later for normal values.
-
- boolean round = false;
- boolean sticky = false;
- int bitsCopied=0;
- int nextShift=0;
- long significand=0L;
- // First iteration is different, since we only copy
- // from the leading significand bit; one more exponent
- // adjust will be needed...
-
- // IMPORTANT: make leadingDigit a long to avoid
- // surprising shift semantics!
- long leadingDigit = getHexDigit(significandString, 0);
-
- /*
- * Left shift the leading digit (53 - (bit position of
- * leading 1 in digit)); this sets the top bit of the
- * significand to 1. The nextShift value is adjusted
- * to take into account the number of bit positions of
- * the leadingDigit actually used. Finally, the
- * exponent is adjusted to normalize the significand
- * as a binary value, not just a hex value.
- */
- if (leadingDigit == 1) {
- significand |= leadingDigit << 52;
- nextShift = 52 - 4;
- /* exponent += 0 */ }
- else if (leadingDigit <= 3) { // [2, 3]
- significand |= leadingDigit << 51;
- nextShift = 52 - 5;
- exponent += 1;
- }
- else if (leadingDigit <= 7) { // [4, 7]
- significand |= leadingDigit << 50;
- nextShift = 52 - 6;
- exponent += 2;
- }
- else if (leadingDigit <= 15) { // [8, f]
- significand |= leadingDigit << 49;
- nextShift = 52 - 7;
- exponent += 3;
- } else {
- throw new AssertionError("Result from digit converstion too large!");
- }
- // The preceding if-else could be replaced by a single
- // code block based on the high-order bit set in
- // leadingDigit. Given leadingOnePosition,
-
- // significand |= leadingDigit << (SIGNIFICAND_WIDTH - leadingOnePosition);
- // nextShift = 52 - (3 + leadingOnePosition);
- // exponent += (leadingOnePosition-1);
-
-
- /*
- * Now the exponent variable is equal to the normalized
- * binary exponent. Code below will make representation
- * adjustments if the exponent is incremented after
- * rounding (includes overflows to infinity) or if the
- * result is subnormal.
- */
-
- // Copy digit into significand until the significand can't
- // hold another full hex digit or there are no more input
- // hex digits.
- int i = 0;
- for(i = 1;
- i < signifLength && nextShift >= 0;
- i++) {
- long currentDigit = getHexDigit(significandString, i);
- significand |= (currentDigit << nextShift);
- nextShift-=4;
- }
-
- // After the above loop, the bulk of the string is copied.
- // Now, we must copy any partial hex digits into the
- // significand AND compute the round bit and start computing
- // sticky bit.
-
- if ( i < signifLength ) { // at least one hex input digit exists
- long currentDigit = getHexDigit(significandString, i);
-
- // from nextShift, figure out how many bits need
- // to be copied, if any
- switch(nextShift) { // must be negative
- case -1:
- // three bits need to be copied in; can
- // set round bit
- significand |= ((currentDigit & 0xEL) >> 1);
- round = (currentDigit & 0x1L) != 0L;
- break;
-
- case -2:
- // two bits need to be copied in; can
- // set round and start sticky
- significand |= ((currentDigit & 0xCL) >> 2);
- round = (currentDigit &0x2L) != 0L;
- sticky = (currentDigit & 0x1L) != 0;
- break;
-
- case -3:
- // one bit needs to be copied in
- significand |= ((currentDigit & 0x8L)>>3);
- // Now set round and start sticky, if possible
- round = (currentDigit &0x4L) != 0L;
- sticky = (currentDigit & 0x3L) != 0;
- break;
-
- case -4:
- // all bits copied into significand; set
- // round and start sticky
- round = ((currentDigit & 0x8L) != 0); // is top bit set?
- // nonzeros in three low order bits?
- sticky = (currentDigit & 0x7L) != 0;
- break;
-
- default:
- throw new AssertionError("Unexpected shift distance remainder.");
- // break;
- }
-
- // Round is set; sticky might be set.
-
- // For the sticky bit, it suffices to check the
- // current digit and test for any nonzero digits in
- // the remaining unprocessed input.
- i++;
- while(i < signifLength && !sticky) {
- currentDigit = getHexDigit(significandString,i);
- sticky = sticky || (currentDigit != 0);
- i++;
- }
-
- }
- // else all of string was seen, round and sticky are
- // correct as false.
-
-
- // Check for overflow and update exponent accordingly.
-
- if (exponent > DoubleConsts.MAX_EXPONENT) { // Infinite result
- // overflow to properly signed infinity
- return new FormattedFloatingDecimal(sign * Double.POSITIVE_INFINITY);
- } else { // Finite return value
- if (exponent <= DoubleConsts.MAX_EXPONENT && // (Usually) normal result
- exponent >= DoubleConsts.MIN_EXPONENT) {
-
- // The result returned in this block cannot be a
- // zero or subnormal; however after the
- // significand is adjusted from rounding, we could
- // still overflow in infinity.
-
- // AND exponent bits into significand; if the
- // significand is incremented and overflows from
- // rounding, this combination will update the
- // exponent correctly, even in the case of
- // Double.MAX_VALUE overflowing to infinity.
-
- significand = (( ((long)exponent +
- (long)DoubleConsts.EXP_BIAS) <<
- (DoubleConsts.SIGNIFICAND_WIDTH-1))
- & DoubleConsts.EXP_BIT_MASK) |
- (DoubleConsts.SIGNIF_BIT_MASK & significand);
-
- } else { // Subnormal or zero
- // (exponent < DoubleConsts.MIN_EXPONENT)
-
- if (exponent < (DoubleConsts.MIN_SUB_EXPONENT -1 )) {
- // No way to round back to nonzero value
- // regardless of significand if the exponent is
- // less than -1075.
- return new FormattedFloatingDecimal(sign * 0.0);
- } else { // -1075 <= exponent <= MIN_EXPONENT -1 = -1023
- /*
- * Find bit position to round to; recompute
- * round and sticky bits, and shift
- * significand right appropriately.
- */
-
- sticky = sticky || round;
- round = false;
-
- // Number of bits of significand to preserve is
- // exponent - abs_min_exp +1
- // check:
- // -1075 +1074 + 1 = 0
- // -1023 +1074 + 1 = 52
-
- int bitsDiscarded = 53 -
- ((int)exponent - DoubleConsts.MIN_SUB_EXPONENT + 1);
- assert bitsDiscarded >= 1 && bitsDiscarded <= 53;
-
- // What to do here:
- // First, isolate the new round bit
- round = (significand & (1L << (bitsDiscarded -1))) != 0L;
- if (bitsDiscarded > 1) {
- // create mask to update sticky bits; low
- // order bitsDiscarded bits should be 1
- long mask = ~((~0L) << (bitsDiscarded -1));
- sticky = sticky || ((significand & mask) != 0L ) ;
- }
-
- // Now, discard the bits
- significand = significand >> bitsDiscarded;
-
- significand = (( ((long)(DoubleConsts.MIN_EXPONENT -1) + // subnorm exp.
- (long)DoubleConsts.EXP_BIAS) <<
- (DoubleConsts.SIGNIFICAND_WIDTH-1))
- & DoubleConsts.EXP_BIT_MASK) |
- (DoubleConsts.SIGNIF_BIT_MASK & significand);
- }
- }
-
- // The significand variable now contains the currently
- // appropriate exponent bits too.
-
- /*
- * Determine if significand should be incremented;
- * making this determination depends on the least
- * significant bit and the round and sticky bits.
- *
- * Round to nearest even rounding table, adapted from
- * table 4.7 in "Computer Arithmetic" by IsraelKoren.
- * The digit to the left of the "decimal" point is the
- * least significant bit, the digits to the right of
- * the point are the round and sticky bits
- *
- * Number Round(x)
- * x0.00 x0.
- * x0.01 x0.
- * x0.10 x0.
- * x0.11 x1. = x0. +1
- * x1.00 x1.
- * x1.01 x1.
- * x1.10 x1. + 1
- * x1.11 x1. + 1
- */
- boolean incremented = false;
- boolean leastZero = ((significand & 1L) == 0L);
- if( ( leastZero && round && sticky ) ||
- ((!leastZero) && round )) {
- incremented = true;
- significand++;
- }
-
- FormattedFloatingDecimal fd = new FormattedFloatingDecimal(FpUtils.rawCopySign(
- Double.longBitsToDouble(significand),
- sign));
-
- /*
- * Set roundingDir variable field of fd properly so
- * that the input string can be properly rounded to a
- * float value. There are two cases to consider:
- *
- * 1. rounding to double discards sticky bit
- * information that would change the result of a float
- * rounding (near halfway case between two floats)
- *
- * 2. rounding to double rounds up when rounding up
- * would not occur when rounding to float.
- *
- * For former case only needs to be considered when
- * the bits rounded away when casting to float are all
- * zero; otherwise, float round bit is properly set
- * and sticky will already be true.
- *
- * The lower exponent bound for the code below is the
- * minimum (normalized) subnormal exponent - 1 since a
- * value with that exponent can round up to the
- * minimum subnormal value and the sticky bit
- * information must be preserved (i.e. case 1).
- */
- if ((exponent >= FloatConsts.MIN_SUB_EXPONENT-1) &&
- (exponent <= FloatConsts.MAX_EXPONENT ) ){
- // Outside above exponent range, the float value
- // will be zero or infinity.
-
- /*
- * If the low-order 28 bits of a rounded double
- * significand are 0, the double could be a
- * half-way case for a rounding to float. If the
- * double value is a half-way case, the double
- * significand may have to be modified to round
- * the the right float value (see the stickyRound
- * method). If the rounding to double has lost
- * what would be float sticky bit information, the
- * double significand must be incremented. If the
- * double value's significand was itself
- * incremented, the float value may end up too
- * large so the increment should be undone.
- */
- if ((significand & 0xfffffffL) == 0x0L) {
- // For negative values, the sign of the
- // roundDir is the same as for positive values
- // since adding 1 increasing the significand's
- // magnitude and subtracting 1 decreases the
- // significand's magnitude. If neither round
- // nor sticky is true, the double value is
- // exact and no adjustment is required for a
- // proper float rounding.
- if( round || sticky) {
- if (leastZero) { // prerounding lsb is 0
- // If round and sticky were both true,
- // and the least significant
- // significand bit were 0, the rounded
- // significand would not have its
- // low-order bits be zero. Therefore,
- // we only need to adjust the
- // significand if round XOR sticky is
- // true.
- if (round ^ sticky) {
- fd.roundDir = 1;
- }
- }
- else { // prerounding lsb is 1
- // If the prerounding lsb is 1 and the
- // resulting significand has its
- // low-order bits zero, the significand
- // was incremented. Here, we undo the
- // increment, which will ensure the
- // right guard and sticky bits for the
- // float rounding.
- if (round)
- fd.roundDir = -1;
- }
- }
- }
- }
-
- fd.fromHex = true;
- return fd;
- }
- }
- }
-
- /**
- * Return <code>s</code> with any leading zeros removed.
- */
- static String stripLeadingZeros(String s) {
- return s.replaceFirst("^0+", "");
- }
-
- /**
- * Extract a hexadecimal digit from position <code>position</code>
- * of string <code>s</code>.
- */
- static int getHexDigit(String s, int position) {
- int value = Character.digit(s.charAt(position), 16);
- if (value <= -1 || value >= 16) {
- throw new AssertionError("Unxpected failure of digit converstion of " +
- s.charAt(position));
- }
- return value;
- }
-
-
}