Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   /*
    * Copyright 2003-2004 Sun Microsystems, Inc.  All Rights Reserved.
    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    *
    * This code is free software; you can redistribute it and/or modify it
    * under the terms of the GNU General Public License version 2 only, as
    * published by the Free Software Foundation.  Sun designates this
    * particular file as subject to the "Classpath" exception as provided
    * by Sun in the LICENSE file that accompanied this code.
   *
   * This code is distributed in the hope that it will be useful, but WITHOUT
   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   * version 2 for more details (a copy is included in the LICENSE file that
   * accompanied this code).
   *
   * You should have received a copy of the GNU General Public License version
   * 2 along with this work; if not, write to the Free Software Foundation,
   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   *
   * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   * CA 95054 USA or visit www.sun.com if you need additional information or
   * have any questions.
   */
  
  package sun.misc;
  
  import sun.misc.FpUtils;
  import java.util.regex.*;
  
  public class FormattedFloatingDecimal{
      boolean     isExceptional;
      boolean     isNegative;
      int         decExponent;  // value set at construction, then immutable
      int         decExponentRounded;
      char        digits[];
      int         nDigits;
      int         bigIntExp;
      int         bigIntNBits;
      boolean     mustSetRoundDir = false;
      boolean     fromHex = false;
      int         roundDir = 0; // set by doubleValue
      int         precision;    // number of digits to the right of decimal
  
      public enum Form { SCIENTIFIC, COMPATIBLE, DECIMAL_FLOAT, GENERAL };
  
      private Form form;
  
      private     FormattedFloatingDecimalboolean negSignint decExponentchar []digitsint nboolean eint precisionForm form )
      {
           = negSign;
           = e;
          this. = decExponent;
          this. = digits;
          this. = n;
          this. = precision;
          this. = form;
      }
  
      /*
       * Constants of the implementation
       * Most are IEEE-754 related.
       * (There are more really boring constants at the end.)
       */
      static final long   signMask = 0x8000000000000000L;
      static final long   expMask  = 0x7ff0000000000000L;
      static final long   fractMask= ~(|);
      static final int    expShift = 52;
      static final int    expBias  = 1023;
      static final long   fractHOB = ( 1L<< ); // assumed High-Order bit
      static final long   expOne   = ((long))<<// exponent of 1.0
      static final int    maxSmallBinExp = 62;
      static final int    minSmallBinExp = -( 63 / 3 );
      static final int    maxDecimalDigits = 15;
      static final int    maxDecimalExponent = 308;
      static final int    minDecimalExponent = -324;
      static final int    bigDecimalExponent = 324; // i.e. abs(minDecimalExponent)
  
      static final long   highbyte = 0xff00000000000000L;
      static final long   highbit  = 0x8000000000000000L;
      static final long   lowbytes = ~;
  
      static final int    singleSignMask =    0x80000000;
      static final int    singleExpMask  =    0x7f800000;
      static final int    singleFractMask =   ~(|);
      static final int    singleExpShift  =   23;
      static final int    singleFractHOB  =   1<<;
      static final int    singleExpBias   =   127;
      static final int    singleMaxDecimalDigits = 7;
      static final int    singleMaxDecimalExponent = 38;
      static final int    singleMinDecimalExponent = -45;
  
      static final int    intDecimalDigits = 9;
  
  
      /*
       * count number of bits from high-order 1 bit to low-order 1 bit,
      * inclusive.
      */
     private static int
     countBitslong v ){
         //
         // the strategy is to shift until we get a non-zero sign bit
         // then shift until we have no bits left, counting the difference.
         // we do byte shifting as a hack. Hope it helps.
         //
         if ( v == 0L ) return 0;
 
         while ( ( v &  ) == 0L ){
             v <<= 8;
         }
         while ( v > 0L ) { // i.e. while ((v&highbit) == 0L )
             v <<= 1;
         }
 
         int n = 0;
         while (( v &  ) != 0L ){
             v <<= 8;
             n += 8;
         }
         while ( v != 0L ){
             v <<= 1;
             n += 1;
         }
         return n;
     }
 
     /*
      * Keep big powers of 5 handy for future reference.
      */
     private static FDBigInt b5p[];
 
     private static synchronized FDBigInt
     big5powint p ){
         assert p >= 0 : p// negative power of 5
         if (  == null ){
              = new FDBigIntp+1 ];
         }else if (. <= p ){
             FDBigInt t[] = new FDBigIntp+1 ];
             System.arraycopy, 0, t, 0, . );
              = t;
         }
         if ( [p] != null )
             return [p];
         else if ( p < . )
             return [p] = new FDBigInt[p] );
         else if ( p < . )
             return [p] = new FDBigInt[p] );
         else {
             // construct the value.
             // recursively.
             int qr;
             // in order to compute 5^p,
             // compute its square root, 5^(p/2) and square.
             // or, let q = p / 2, r = p -q, then
             // 5^p = 5^(q+r) = 5^q * 5^r
             q = p >> 1;
             r = p - q;
             FDBigInt bigq =  [q];
             if ( bigq == null )
                 bigq = big5pow ( q );
             if ( r < . ){
                 return ([p] = bigq.mult[r] ) );
             }else{
                 FDBigInt bigr = r ];
                 if ( bigr == null )
                     bigr = big5powr );
                 return ([p] = bigq.multbigr ) );
             }
         }
     }
 
     //
     // a common operation
     //
     private static FDBigInt
     multPow52FDBigInt vint p5int p2 ){
         if ( p5 != 0 ){
             if ( p5 < . ){
                 v = v.mult[p5] );
             } else {
                 v = v.multbig5powp5 ) );
             }
         }
         if ( p2 != 0 ){
             v.lshiftMep2 );
         }
         return v;
     }
 
     //
     // another common operation
     //
     private static FDBigInt
     constructPow52int p5int p2 ){
         FDBigInt v = new FDBigIntbig5powp5 ) );
         if ( p2 != 0 ){
             v.lshiftMep2 );
         }
         return v;
     }
 
     /*
      * Make a floating double into a FDBigInt.
      * This could also be structured as a FDBigInt
      * constructor, but we'd have to build a lot of knowledge
      * about floating-point representation into it, and we don't want to.
      *
      * AS A SIDE EFFECT, THIS METHOD WILL SET THE INSTANCE VARIABLES
      * bigIntExp and bigIntNBits
      *
      */
     private FDBigInt
     doubleToBigIntdouble dval ){
         long lbits = Double.doubleToLongBitsdval ) & ~;
         int binexp = (int)(lbits >>> );
         lbits &= ;
         if ( binexp > 0 ){
             lbits |= ;
         } else {
             assert lbits != 0L : lbits// doubleToBigInt(0.0)
             binexp +=1;
             while ( (lbits &  ) == 0L){
                 lbits <<= 1;
                 binexp -= 1;
             }
         }
         binexp -= ;
         int nbits = countBitslbits );
         /*
          * We now know where the high-order 1 bit is,
          * and we know how many there are.
          */
         int lowOrderZeros = +1-nbits;
         lbits >>>= lowOrderZeros;
 
          = binexp+1-nbits;
          = nbits;
         return new FDBigIntlbits );
     }
 
     /*
      * Compute a number that is the ULP of the given value,
      * for purposes of addition/subtraction. Generally easy.
      * More difficult if subtracting and the argument
      * is a normalized a power of 2, as the ULP changes at these points.
      */
     private static double
     ulpdouble dvalboolean subtracting ){
         long lbits = Double.doubleToLongBitsdval ) & ~;
         int binexp = (int)(lbits >>> );
         double ulpval;
         if ( subtracting && ( binexp >=  ) && ((lbits&) == 0L) ){
             // for subtraction from normalized, powers of 2,
             // use next-smaller exponent
             binexp -= 1;
         }
         if ( binexp >  ){
             ulpval = Double.longBitsToDouble( ((long)(binexp-))<< );
         } else if ( binexp == 0 ){
             ulpval = .;
         } else {
             ulpval = Double.longBitsToDouble( 1L<<(binexp-1) );
         }
         if ( subtracting ) ulpval = - ulpval;
 
         return ulpval;
     }
 
     /*
      * Round a double to a float.
      * In addition to the fraction bits of the double,
      * look at the class instance variable roundDir,
      * which should help us avoid double-rounding error.
      * roundDir was set in hardValueOf if the estimate was
      * close enough, but not exact. It tells us which direction
      * of rounding is preferred.
      */
     float
     stickyRounddouble dval ){
         long lbits = Double.doubleToLongBitsdval );
         long binexp = lbits & ;
         if ( binexp == 0L || binexp ==  ){
             // what we have here is special.
             // don't worry, the right thing will happen.
             return (floatdval;
         }
         lbits += (long)// hack-o-matic.
         return (float)Double.longBitsToDoublelbits );
     }
 
 
     /*
      * This is the easy subcase --
      * all the significant bits, after scaling, are held in lvalue.
      * negSign and decExponent tell us what processing and scaling
      * has already been done. Exceptional cases have already been
      * stripped out.
      * In particular:
      * lvalue is a finite number (not Inf, nor NaN)
      * lvalue > 0L (not zero, nor negative).
      *
      * The only reason that we develop the digits here, rather than
      * calling on Long.toString() is that we can do it a little faster,
      * and besides want to treat trailing 0s specially. If Long.toString
      * changes, we should re-evaluate this strategy!
      */
     private void
     developLongDigitsint decExponentlong lvaluelong insignificant ){
         char digits[];
         int  ndigits;
         int  digitno;
         int  c;
         //
         // Discard non-significant low-order bits, while rounding,
         // up to insignificant value.
         int i;
         for ( i = 0; insignificant >= 10L; i++ )
             insignificant /= 10L;
         if ( i != 0 ){
             long pow10 = [i] << i// 10^i == 5^i * 2^i;
             long residue = lvalue % pow10;
             lvalue /= pow10;
             decExponent += i;
             if ( residue >= (pow10>>1) ){
                 // round up based on the low-order bits we're discarding
                 lvalue++;
             }
         }
         if ( lvalue <= . ){
             assert lvalue > 0L : lvalue// lvalue <= 0
             // even easier subcase!
             // can do int arithmetic rather than long!
             int  ivalue = (int)lvalue;
             ndigits = 10;
             digits = (char[])(.get());
             digitno = ndigits-1;
             c = ivalue%10;
             ivalue /= 10;
             while ( c == 0 ){
                 decExponent++;
                 c = ivalue%10;
                 ivalue /= 10;
             }
             while ( ivalue != 0){
                 digits[digitno--] = (char)(c+'0');
                 decExponent++;
                 c = ivalue%10;
                 ivalue /= 10;
             }
             digits[digitno] = (char)(c+'0');
         } else {
             // same algorithm as above (same bugs, too )
             // but using long arithmetic.
             ndigits = 20;
             digits = (char[])(.get());
             digitno = ndigits-1;
             c = (int)(lvalue%10L);
             lvalue /= 10L;
             while ( c == 0 ){
                 decExponent++;
                 c = (int)(lvalue%10L);
                 lvalue /= 10L;
             }
             while ( lvalue != 0L ){
                 digits[digitno--] = (char)(c+'0');
                 decExponent++;
                 c = (int)(lvalue%10L);
                 lvalue /= 10;
             }
             digits[digitno] = (char)(c+'0');
         }
         char result [];
         ndigits -= digitno;
         result = new charndigits ];
         System.arraycopydigitsdigitnoresult, 0, ndigits );
         this. = result;
         this. = decExponent+1;
         this. = ndigits;
     }
 
     //
     // add one to the least significant digit.
     // in the unlikely event there is a carry out,
     // deal with it.
     // assert that this will only happen where there
     // is only one digit, e.g. (float)1e-44 seems to do it.
     //
     private void
     roundup(){
         int i;
         int q = i = (-1)];
         if ( q == '9' ){
             while ( q == '9' && i > 0 ){
                 [i] = '0';
                 q = [--i];
             }
             if ( q == '9' ){
                 // carryout! High-order 1, rest 0s, larger exp.
                  += 1;
                 [0] = '1';
                 return;
             }
             // else fall through.
         }
         [i] = (char)(q+1);
     }
 
     // Given the desired number of digits predict the result's exponent.
     private int checkExponent(int length) {
         if (length >=  || length < 0)
             return ;
 
         for (int i = 0; i < lengthi++)
             if ([i] != '9')
                 // a '9' anywhere in digits will absorb the round
                 return ;
         return  + ([length] >= '5' ? 1 : 0);
     }
 
     // Unlike roundup(), this method does not modify digits.  It also
     // rounds at a particular precision.
     private char [] applyPrecision(int length) {
         char [] result = new char[];
         for (int i = 0; i < result.lengthi++) result[i] = '0';
 
         if (length >=  || length < 0) {
             // no rounding necessary
             System.arraycopy(, 0, result, 0, );
             return result;
         }
         if (length == 0) {
             // only one digit (0 or 1) is returned because the precision
             // excludes all significant digits
             if ([0] >= '5') {
                 result[0] = '1';
             }
             return result;
         }
 
         int i = length;
         int q = [i];
         if (q >= '5' && i > 0) {
             q = [--i];
             if ( q == '9' ) {
                 while ( q == '9' && i > 0 ){
                     q = [--i];
                 }
                 if ( q == '9' ){
                     // carryout! High-order 1, rest 0s, larger exp.
                     result[0] = '1';
                     return result;
                 }
             }
             result[i] = (char)(q + 1);
         }
         while (--i >= 0) {
             result[i] = [i];
         }
         return result;
     }
 
     /*
      * FIRST IMPORTANT CONSTRUCTOR: DOUBLE
      */
     public FormattedFloatingDecimaldouble d )
     {
         this(d..);
     }
 
     public FormattedFloatingDecimaldouble dint precisionForm form )
     {
         long    dBits = Double.doubleToLongBitsd );
         long    fractBits;
         int     binExp;
         int     nSignificantBits;
 
         this. = precision;
         this.      = form;
 
         // discover and delete sign
         if ( (dBits&) != 0 ){
              = true;
             dBits ^= ;
         } else {
              = false;
         }
         // Begin to unpack
         // Discover obvious special cases of NaN and Infinity.
         binExp = (int)( (dBits&) >>  );
         fractBits = dBits&;
         if ( binExp == (int)(>>) ) {
              = true;
             if ( fractBits == 0L ){
                  =  ;
             } else {
                  = ;
                  = false// NaN has no sign!
             }
              = .;
             return;
         }
          = false;
         // Finish unpacking
         // Normalize denormalized numbers.
         // Insert assumed high-order bit for normalized numbers.
         // Subtract exponent bias.
         if ( binExp == 0 ){
             if ( fractBits == 0L ){
                 // not a denorm, just a 0!
                  = 0;
                  = ;
                  = 1;
                 return;
             }
             while ( (fractBits&) == 0L ){
                 fractBits <<= 1;
                 binExp -= 1;
             }
             nSignificantBits =  + binExp +1; // recall binExp is  - shift count.
             binExp += 1;
         } else {
             fractBits |= ;
             nSignificantBits = +1;
         }
         binExp -= ;
         // call the routine that actually does all the hard work.
         dtoabinExpfractBitsnSignificantBits );
     }
 
     /*
      * SECOND IMPORTANT CONSTRUCTOR: SINGLE
      */
     public FormattedFloatingDecimalfloat f )
     {
         this(f..);
     }
     public FormattedFloatingDecimalfloat fint precisionForm form )
     {
         int     fBits = Float.floatToIntBitsf );
         int     fractBits;
         int     binExp;
         int     nSignificantBits;
 
         this. = precision;
         this.      = form;
 
         // discover and delete sign
         if ( (fBits&) != 0 ){
              = true;
             fBits ^= ;
         } else {
              = false;
         }
         // Begin to unpack
         // Discover obvious special cases of NaN and Infinity.
         binExp = (int)( (fBits&) >>  );
         fractBits = fBits&;
         if ( binExp == (int)(>>) ) {
              = true;
             if ( fractBits == 0L ){
                  =  ;
             } else {
                  = ;
                  = false// NaN has no sign!
             }
              = .;
             return;
         }
          = false;
         // Finish unpacking
         // Normalize denormalized numbers.
         // Insert assumed high-order bit for normalized numbers.
         // Subtract exponent bias.
         if ( binExp == 0 ){
             if ( fractBits == 0 ){
                 // not a denorm, just a 0!
                  = 0;
                  = ;
                  = 1;
                 return;
             }
             while ( (fractBits&) == 0 ){
                 fractBits <<= 1;
                 binExp -= 1;
             }
             nSignificantBits =  + binExp +1; // recall binExp is  - shift count.
             binExp += 1;
         } else {
             fractBits |= ;
             nSignificantBits = +1;
         }
         binExp -= ;
         // call the routine that actually does all the hard work.
         dtoabinExp, ((long)fractBits)<<(-), nSignificantBits );
     }
 
     private void
     dtoaint binExplong fractBitsint nSignificantBits )
     {
         int     nFractBits// number of significant bits of fractBits;
         int     nTinyBits;  // number of these to the right of the point.
         int     decExp;
 
         // Examine number. Determine if it is an easy case,
         // which we can do pretty trivially using float/long conversion,
         // or whether we must do real work.
         nFractBits = countBitsfractBits );
         nTinyBits = Math.max( 0, nFractBits - binExp - 1 );
         if ( binExp <=  && binExp >=  ){
             // Look more closely at the number to decide if,
             // with scaling by 10^nTinyBits, the result will fit in
             // a long.
             if ( (nTinyBits < .) && ((nFractBits + [nTinyBits]) < 64 ) ){
                 /*
                  * We can do this:
                  * take the fraction bits, which are normalized.
                  * (a) nTinyBits == 0: Shift left or right appropriately
                  *     to align the binary point at the extreme right, i.e.
                  *     where a long int point is expected to be. The integer
                  *     result is easily converted to a string.
                  * (b) nTinyBits > 0: Shift right by expShift-nFractBits,
                  *     which effectively converts to long and scales by
                  *     2^nTinyBits. Then multiply by 5^nTinyBits to
                  *     complete the scaling. We know this won't overflow
                  *     because we just counted the number of bits necessary
                  *     in the result. The integer you get from this can
                  *     then be converted to a string pretty easily.
                  */
                 long halfULP;
                 if ( nTinyBits == 0 ) {
                     if ( binExp > nSignificantBits ){
                         halfULP = 1L << ( binExp-nSignificantBits-1);
                     } else {
                         halfULP = 0L;
                     }
                     if ( binExp >=  ){
                         fractBits <<= (binExp-);
                     } else {
                         fractBits >>>= (-binExp) ;
                     }
                     developLongDigits( 0, fractBitshalfULP );
                     return;
                 }
                 /*
                  * The following causes excess digits to be printed
                  * out in the single-float case. Our manipulation of
                  * halfULP here is apparently not correct. If we
                  * better understand how this works, perhaps we can
                  * use this special case again. But for the time being,
                  * we do not.
                  * else {
                  *     fractBits >>>= expShift+1-nFractBits;
                  *     fractBits *= long5pow[ nTinyBits ];
                  *     halfULP = long5pow[ nTinyBits ] >> (1+nSignificantBits-nFractBits);
                  *     developLongDigits( -nTinyBits, fractBits, halfULP );
                  *     return;
                  * }
                  */
             }
         }
         /*
          * This is the hard case. We are going to compute large positive
          * integers B and S and integer decExp, s.t.
          *      d = ( B / S ) * 10^decExp
          *      1 <= B / S < 10
          * Obvious choices are:
          *      decExp = floor( log10(d) )
          *      B      = d * 2^nTinyBits * 10^max( 0, -decExp )
          *      S      = 10^max( 0, decExp) * 2^nTinyBits
          * (noting that nTinyBits has already been forced to non-negative)
          * I am also going to compute a large positive integer
          *      M      = (1/2^nSignificantBits) * 2^nTinyBits * 10^max( 0, -decExp )
          * i.e. M is (1/2) of the ULP of d, scaled like B.
          * When we iterate through dividing B/S and picking off the
          * quotient bits, we will know when to stop when the remainder
          * is <= M.
          *
          * We keep track of powers of 2 and powers of 5.
          */
 
         /*
          * Estimate decimal exponent. (If it is small-ish,
          * we could double-check.)
          *
          * First, scale the mantissa bits such that 1 <= d2 < 2.
          * We are then going to estimate
          *          log10(d2) ~=~  (d2-1.5)/1.5 + log(1.5)
          * and so we can estimate
          *      log10(d) ~=~ log10(d2) + binExp * log10(2)
          * take the floor and call it decExp.
          * FIXME -- use more precise constants here. It costs no more.
          */
         double d2 = Double.longBitsToDouble(
              | ( fractBits &~  ) );
         decExp = (int)Math.floor(
             (d2-1.5D)*0.289529654D + 0.176091259 + (double)binExp * 0.301029995663981 );
         int B2B5// powers of 2 and powers of 5, respectively, in B
         int S2S5// powers of 2 and powers of 5, respectively, in S
         int M2M5// powers of 2 and powers of 5, respectively, in M
         int Bbits// binary digits needed to represent B, approx.
         int tenSbits// binary digits needed to represent 10*S, approx.
         FDBigInt SvalBvalMval;
 
         B5 = Math.max( 0, -decExp );
         B2 = B5 + nTinyBits + binExp;
 
         S5 = Math.max( 0, decExp );
         S2 = S5 + nTinyBits;
 
         M5 = B5;
         M2 = B2 - nSignificantBits;
 
         /*
          * the long integer fractBits contains the (nFractBits) interesting
          * bits from the mantissa of d ( hidden 1 added if necessary) followed
          * by (expShift+1-nFractBits) zeros. In the interest of compactness,
          * I will shift out those zeros before turning fractBits into a
          * FDBigInt. The resulting whole number will be
          *      d * 2^(nFractBits-1-binExp).
          */
         fractBits >>>= (+1-nFractBits);
         B2 -= nFractBits-1;
         int common2factor = Math.minB2S2 );
         B2 -= common2factor;
         S2 -= common2factor;
         M2 -= common2factor;
 
         /*
          * HACK!! For exact powers of two, the next smallest number
          * is only half as far away as we think (because the meaning of
          * ULP changes at power-of-two bounds) for this reason, we
          * hack M2. Hope this works.
          */
         if ( nFractBits == 1 )
             M2 -= 1;
 
         if ( M2 < 0 ){
             // oops.
             // since we cannot scale M down far enough,
             // we must scale the other values up.
             B2 -= M2;
             S2 -= M2;
             M2 =  0;
         }
         /*
          * Construct, Scale, iterate.
          * Some day, we'll write a stopping test that takes
          * account of the assymetry of the spacing of floating-point
          * numbers below perfect powers of 2
          * 26 Sept 96 is not that day.
          * So we use a symmetric test.
          */
         char digits[] = this. = new char[18];
         int  ndigit = 0;
         boolean lowhigh;
         long lowDigitDifference;
         int  q;
 
         /*
          * Detect the special cases where all the numbers we are about
          * to compute will fit in int or long integers.
          * In these cases, we will avoid doing FDBigInt arithmetic.
          * We use the same algorithms, except that we "normalize"
          * our FDBigInts before iterating. This is to make division easier,
          * as it makes our fist guess (quotient of high-order words)
          * more accurate!
          *
          * Some day, we'll write a stopping test that takes
          * account of the assymetry of the spacing of floating-point
          * numbers below perfect powers of 2
          * 26 Sept 96 is not that day.
          * So we use a symmetric test.
          */
         Bbits = nFractBits + B2 + (( B5 < . )? [B5] : ( B5*3 ));
         tenSbits = S2+1 + (( (S5+1) < . )? [(S5+1)] : ( (S5+1)*3 ));
         if ( Bbits < 64 && tenSbits < 64){
             if ( Bbits < 32 && tenSbits < 32){
                 // wa-hoo! They're all ints!
                 int b = ((int)fractBits * [B5] ) << B2;
                 int s = [S5] << S2;
                 int m = [M5] << M2;
                 int tens = s * 10;
                 /*
                  * Unroll the first iteration. If our decExp estimate
                  * was too high, our first quotient will be zero. In this
                  * case, we discard it and decrement decExp.
                  */
                 ndigit = 0;
                 q = b / s;
                 b = 10 * ( b % s );
                 m *= 10;
                 low  = (b <  m );
                 high = (b+m > tens );
                 assert q < 10 : q// excessively large digit
                 if ( (q == 0) && ! high ){
                     // oops. Usually ignore leading zero.
                     decExp--;
                 } else {
                     digits[ndigit++] = (char)('0' + q);
                 }
                 /*
                  * HACK! Java spec sez that we always have at least
                  * one digit after the . in either F- or E-form output.
                  * Thus we will need more than one digit if we're using
                  * E-form
                  */
                 if (! ( == . && -3 < decExp && decExp < 8)) {
                     high = low = false;
                 }
                 while( ! low && ! high ){
                     q = b / s;
                     b = 10 * ( b % s );
                     m *= 10;
                     assert q < 10 : q// excessively large digit
                     if ( m > 0L ){
                         low  = (b <  m );
                         high = (b+m > tens );
                     } else {
                         // hack -- m might overflow!
                         // in this case, it is certainly > b,
                         // which won't
                         // and b+m > tens, too, since that has overflowed
                         // either!
                         low = true;
                         high = true;
                     }
                     digits[ndigit++] = (char)('0' + q);
                 }
                 lowDigitDifference = (b<<1) - tens;
             } else {
                 // still good! they're all longs!
                 long b = (fractBits * [B5] ) << B2;
                 long s = [S5] << S2;
                 long m = [M5] << M2;
                 long tens = s * 10L;
                 /*
                  * Unroll the first iteration. If our decExp estimate
                  * was too high, our first quotient will be zero. In this
                  * case, we discard it and decrement decExp.
                  */
                 ndigit = 0;
                 q = (int) ( b / s );
                 b = 10L * ( b % s );
                 m *= 10L;
                 low  = (b <  m );
                 high = (b+m > tens );
                 assert q < 10 : q// excessively large digit
                 if ( (q == 0) && ! high ){
                     // oops. Usually ignore leading zero.
                     decExp--;
                 } else {
                     digits[ndigit++] = (char)('0' + q);
                 }
                 /*
                  * HACK! Java spec sez that we always have at least
                  * one digit after the . in either F- or E-form output.
                  * Thus we will need more than one digit if we're using
                  * E-form
                  */
                 if (! ( == . && -3 < decExp && decExp < 8)) {
                     high = low = false;
                 }
                 while( ! low && ! high ){
                     q = (int) ( b / s );
                     b = 10 * ( b % s );
                     m *= 10;
                     assert q < 10 : q;  // excessively large digit
                     if ( m > 0L ){
                         low  = (b <  m );
                         high = (b+m > tens );
                     } else {
                         // hack -- m might overflow!
                         // in this case, it is certainly > b,
                         // which won't
                         // and b+m > tens, too, since that has overflowed
                         // either!
                         low = true;
                         high = true;
                     }
                     digits[ndigit++] = (char)('0' + q);
                 }
                 lowDigitDifference = (b<<1) - tens;
             }
         } else {
             FDBigInt tenSval;
             int  shiftBias;
 
             /*
              * We really must do FDBigInt arithmetic.
              * Fist, construct our FDBigInt initial values.
              */
             Bval = multPow52new FDBigIntfractBits  ), B5B2 );
             Sval = constructPow52S5S2 );
             Mval = constructPow52M5M2 );
 
 
             // normalize so that division works better
             Bval.lshiftMeshiftBias = Sval.normalizeMe() );
             Mval.lshiftMeshiftBias );
             tenSval = Sval.mult( 10 );
             /*
              * Unroll the first iteration. If our decExp estimate
              * was too high, our first quotient will be zero. In this
              * case, we discard it and decrement decExp.
              */
             ndigit = 0;
             q = Bval.quoRemIterationSval );
             Mval = Mval.mult( 10 );
             low  = (Bval.cmpMval ) < 0);
             high = (Bval.addMval ).cmptenSval ) > 0 );
             assert q < 10 : q// excessively large digit
             if ( (q == 0) && ! high ){
                 // oops. Usually ignore leading zero.
                 decExp--;
             } else {
                 digits[ndigit++] = (char)('0' + q);
             }
             /*
              * HACK! Java spec sez that we always have at least
              * one digit after the . in either F- or E-form output.
              * Thus we will need more than one digit if we're using
              * E-form
              */
             if (! ( == . && -3 < decExp && decExp < 8)) {
                 high = low = false;
             }
             while( ! low && ! high ){
                 q = Bval.quoRemIterationSval );
                 Mval = Mval.mult( 10 );
                 assert q < 10 : q;  // excessively large digit
                 low  = (Bval.cmpMval ) < 0);
                 high = (Bval.addMval ).cmptenSval ) > 0 );
                 digits[ndigit++] = (char)('0' + q);
             }
             if ( high && low ){
                 Bval.lshiftMe(1);
                 lowDigitDifference = Bval.cmp(tenSval);
             } else
                 lowDigitDifference = 0L; // this here only for flow analysis!
         }
         this. = decExp+1;
         this. = digits;
         this. = ndigit;
         /*
          * Last digit gets rounded based on stopping condition.
          */
         if ( high ){
             if ( low ){
                 if ( lowDigitDifference == 0L ){
                     // it's a tie!
                     // choose based on which digits we like.
                     if ( (digits[-1]&1) != 0 ) roundup();
                 } else if ( lowDigitDifference > 0 ){
                     roundup();
                 }
             } else {
                 roundup();
             }
         }
     }
 
     public String
     toString(){
         // most brain-dead version
         StringBuffer result = new StringBuffer+8 );
         if (  ){ result.append'-' ); }
         if (  ){
             result.append, 0,  );
         } else {
             result.append"0.");
             result.append, 0,  );
             result.append('e');
             result.append );
         }
         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[])(.get());
         int i = getChars(result);
         return new String(result, 0, i);
     }
 
     // returns the exponent before rounding
     public int getExponent() {
         return  - 1;
     }
 
     // returns the exponent after rounding has been done by applyPrecision
     public int getExponentRounded() {
         return  - 1;
     }
 
    public int getChars(char[] result) {
        assert  <= 19 : // generous bound on size of nDigits
        int i = 0;
        if () { result[0] = '-'i = 1; }
        if () {
            System.arraycopy(, 0, resulti);
            i += ;
        } else {
            char digits [] = this.;
            int exp = ;
            switch () {
            case :
                break;
            case :
                exp = checkExponent( + );
                digits = applyPrecision( + );
                break;
            case :
                exp = checkExponent( + 1);
                digits = applyPrecision( + 1);
                break;
            case :
                exp = checkExponent();
                digits = applyPrecision();
                // adjust precision to be the number of digits to right of decimal
                // the real exponent to be output is actually exp - 1, not exp
                if (exp - 1 < -4 || exp - 1 >= ) {
                     = .;
                    --;
                } else {
                     = .;
                     =  - exp;
                }
                break;
            default:
                assert false;
            }
             = exp;
            if (exp > 0
                && (( == . && (exp < 8))
                    || ( == .)))
            {
                // print digits.digits.
                int charLength = Math.min(exp);
                System.arraycopy(digits, 0, resulticharLength);
                i += charLength;
                if (charLength < exp) {
                    charLength = exp-charLength;
                    for (int nz = 0; nz < charLengthnz++)
                        result[i++] = '0';
                    // Do not append ".0" for formatted floats since the user
                    // may request that it be omitted. It is added as necessary
                    // by the Formatter.
                    if ( == .) {
                        result[i++] = '.';
                        result[i++] = '0';
                    }
                } else {
                    // Do not append ".0" for formatted floats since the user
                    // may request that it be omitted. It is added as necessary
                    // by the Formatter.
                    if ( == .) {
                        result[i++] = '.';
                        if (charLength < ) {
                            int t = Math.min( - charLength);
                            System.arraycopy(digitscharLengthresultit);
                            i += t;
                        } else {
                            result[i++] = '0';
                        }
                    } else {
                        int t = Math.min( - charLength);
                        if (t > 0) {
                            result[i++] = '.';
                            System.arraycopy(digitscharLengthresultit);
                            i += t;
                        }
                    }
                }
            } else if (exp <= 0
                       && (( == . && exp > -3)
                       || ( == .)))
            {
                // print 0.0* digits
                result[i++] = '0';
                if (exp != 0) {
                    // write '0' s before the significant digits
                    int t = Math.min(-exp);
                    if (t > 0) {
                        result[i++] = '.';
                        for (int nz = 0; nz < tnz++)
                            result[i++] = '0';
                    }
                }
                int t = Math.min(digits.length + exp);
                if (t > 0) {
                    if (i == 1)
                        result[i++] = '.';
                    // copy only when significant digits are within the precision
                    System.arraycopy(digits, 0, resultit);
                    i += t;
                }
            } else {
                result[i++] = digits[0];
                if ( == .) {
                    result[i++] = '.';
                    if ( > 1) {
                        System.arraycopy(digits, 1, resulti-1);
                        i += -1;
                    } else {
                        result[i++] = '0';
                    }
                    result[i++] = 'E';
                } else {
                    if ( > 1) {
                        int t = Math.min( -1, );
                        if (t > 0) {
                            result[i++] = '.';
                            System.arraycopy(digits, 1, resultit);
                            i += t;
                        }
                    }
                    result[i++] = 'e';
                }
                int e;
                if (exp <= 0) {
                    result[i++] = '-';
                    e = -exp+1;
                } else {
                    if ( != .)
                        result[i++] = '+';
                    e = exp-1;
                }
                // decExponent has 1, 2, or 3, digits
                if (e <= 9) {
                    if ( != .)
                        result[i++] = '0';
                    result[i++] = (char)(e+'0');
                } else if (e <= 99) {
                    result[i++] = (char)(e/10 +'0');
                    result[i++] = (char)(e%10 + '0');
                } else {
                    result[i++] = (char)(e/100+'0');
                    e %= 100;
                    result[i++] = (char)(e/10+'0');
                    result[i++] = (char)(e%10 + '0');
                }
            }
        }
        return i;
    }
    // Per-thread buffer for string/stringbuffer conversion
    private static ThreadLocal perThreadBuffer = new ThreadLocal() {
            protected synchronized Object initialValue() {
                return new char[26];
            }
        };
    // 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[])(.get());
        int i = getChars(result);
        if (buf instanceof StringBuilder)
            ((StringBuilderbuf).append(result, 0, i);
        else if (buf instanceof StringBuffer)
            ((StringBufferbuf).append(result, 0, i);
        else
            assert false;
    }
    public static FormattedFloatingDecimal
        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.charAti ) ){
            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 = ;
                    potentialNaN = true;
                } else {
                    targetChars = ;
                }
                // 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(.// NaN has no sign
                            : new FormattedFloatingDecimal(isNegative?
                                                  .:
                                                  .)) ;
                }
                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 charl ];
            int    nDigits= 0;
            boolean decSeen = false;
            int decPt = 0;
            int nLeadZero = 0;
            int nTrailZero= 0;
        digitLoop:
            while ( i < l ){
                switch ( c = in.charAti ) ){
                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 = ;
                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 = . / 10;
                boolean expOverflow = false;
                switchin.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 = +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 FormattedFloatingDecimalisNegativedecExpdigitsnDigits,  false.. );
        } 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.
     *
     * AS A SIDE EFFECT, SET roundDir TO INDICATE PREFERRED
     * ROUNDING DIRECTION in case the result is really destined
     * for a single-precision float.
     */
    public double
    doubleValue(){
        int     kDigits = Math.min+1 );
        long    lValue;
        double  dValue;
        double  rValuetValue;
        // First, check for NaN and Infinity values
        if( ==  ||  == ) {
            if( == )
                return .;
            else
                return (?.:.);
        }
        else {
            if () {
                 = 0;
            }
            /*
             * convert the lead kDigits to a long integer.
             */
            // (special performance hack: start to do it using int)
            int iValue = (int)[0]-(int)'0';
            int iDigits = Math.minkDigits );
            for ( int i=1; i < iDigitsi++ ){
                iValue = iValue*10 + (int)[i]-(int)'0';
            }
            lValue = (long)iValue;
            for ( int i=iDigitsi < kDigitsi++ ){
                lValue = lValue*10L + (long)((int)[i]-(int)'0');
            }
            dValue = (double)lValue;
            int exp = -kDigits;
            /*
             * lValue now contains a long integer with the value of
             * the first kDigits digits of the number.
             * dValue contains the (double) of the same.
             */
            if (  <=  ){
                /*
                 * possibly an easy case.
                 * We know that the digits can be represented
                 * exactly. And if the exponent isn't too outrageous,
                 * the whole thing can be done with one operation,
                 * thus one rounding error.
                 * Note that all our constructors trim all leading and
                 * trailing zeros, so simple values (including zero)
                 * will always end up here
                 */
                if (exp == 0 || dValue == 0.0)
                    return ()? -dValue : dValue// small floating integer
                else if ( exp >= 0 ){
                    if ( exp <=  ){
                        /*
                         * Can get the answer with one operation,
                         * thus one roundoff.
                         */
                        rValue = dValue * [exp];
                        if (  ){
                            tValue = rValue / [exp];
                             = ( tValue ==  dValue ) ? 0
                                :( tValue < dValue ) ? 1
                                : -1;
                        }
                        return ()? -rValue : rValue;
                    }
                    int slop =  - kDigits;
                    if ( exp <= +slop ){
                        /*
                         * We can multiply dValue by 10^(slop)
                         * and it is still "small" and exact.
                         * Then we can multiply by 10^(exp-slop)
                         * with one rounding.
                         */
                        dValue *= [slop];
                        rValue = dValue * [exp-slop];
                        if (  ){
                            tValue = rValue / [exp-slop];
                             = ( tValue ==  dValue ) ? 0
                                :( tValue < dValue ) ? 1
                                : -1;
                        }
                        return ()? -rValue : rValue;
                    }
                    /*
                     * Else we have a hard case with a positive exp.
                     */
                } else {
                    if ( exp >= - ){
                        /*
                         * Can get the answer in one division.
                         */
                        rValue = dValue / [-exp];
                        tValue = rValue * [-exp];
                        if (  ){
                             = ( tValue ==  dValue ) ? 0
                                :( tValue < dValue ) ? 1
                                : -1;
                        }
                        return ()? -rValue : rValue;
                    }
                    /*
                     * Else we have a hard case with a negative exp.
                     */
                }
            }
            /*
             * Harder cases:
             * The sum of digits plus exponent is greater than
             * what we think we can do with one error.
             *
             * Start by approximating the right answer by,
             * naively, scaling by powers of 10.
             */
            if ( exp > 0 ){
                if (  > +1 ){
                    /*
                     * Lets face it. This is going to be
                     * Infinity. Cut to the chase.
                     */
                    return ()? . : .;
                }
                if ( (exp&15) != 0 ){
                    dValue *= [exp&15];
                }
                if ( (exp>>=4) != 0 ){
                    int j;
                    forj = 0; exp > 1; j++, exp>>=1 ){
                        if ( (exp&1)!=0)
                            dValue *= [j];
                    }
                    /*
                     * The reason for the weird exp > 1 condition
                     * in the above loop was so that the last multiply
                     * would get unrolled. We handle it here.
                     * It could overflow.
                     */
                    double t = dValue * [j];
                    if ( Double.isInfinitet ) ){
                        /*
                         * It did overflow.
                         * Look more closely at the result.
                         * If the exponent is just one too large,
                         * then use the maximum finite as our estimate
                         * value. Else call the result infinity
                         * and punt it.
                         * ( I presume this could happen because
                         * rounding forces the result here to be
                         * an ULP or two larger than
                         * Double.MAX_VALUE ).
                         */
                        t = dValue / 2.0;
                        t *= [j];
                        if ( Double.isInfinitet ) ){
                            return ()? . : .;
                        }
                        t = .;
                    }
                    dValue = t;
                }
            } else if ( exp < 0 ){
                exp = -exp;
                if (  < -1 ){
                    /*
                     * Lets face it. This is going to be
                     * zero. Cut to the chase.
                     */
                    return ()? -0.0 : 0.0;
                }
                if ( (exp&15) != 0 ){
                    dValue /= [exp&15];
                }
                if ( (exp>>=4) != 0 ){
                    int j;
                    forj = 0; exp > 1; j++, exp>>=1 ){
                        if ( (exp&1)!=0)
                            dValue *= [j];
                    }
                    /*
                     * The reason for the weird exp > 1 condition
                     * in the above loop was so that the last multiply
                     * would get unrolled. We handle it here.
                     * It could underflow.
                     */
                    double t = dValue * [j];
                    if ( t == 0.0 ){
                        /*
                         * It did underflow.
                         * Look more closely at the result.
                         * If the exponent is just one too small,
                         * then use the minimum finite as our estimate
                         * value. Else call the result 0.0
                         * and punt it.
                         * ( I presume this could happen because
                         * rounding forces the result here to be
                         * an ULP or two less than
                         * Double.MIN_VALUE ).
                         */
                        t = dValue * 2.0;
                        t *= [j];
                        if ( t == 0.0 ){
                            return ()? -0.0 : 0.0;
                        }
                        t = .;
                    }
                    dValue = t;
                }
            }
            /*
             * dValue is now approximately the result.
             * The hard part is adjusting it, by comparison
             * with FDBigInt arithmetic.
             * Formulate the EXACT big-number result as
             * bigD0 * 10^exp
             */
            FDBigInt bigD0 = new FDBigIntlValuekDigits );
            exp   =  - ;
            correctionLoop:
            while(true){
                /* AS A SIDE EFFECT, THIS METHOD WILL SET THE INSTANCE VARIABLES
                 * bigIntExp and bigIntNBits
                 */
                FDBigInt bigB = doubleToBigIntdValue );
                /*
                 * Scale bigD, bigB appropriately for
                 * big-integer operations.
                 * Naively, we multipy by powers of ten
                 * and powers of two. What we actually do
                 * is keep track of the powers of 5 and
                 * powers of 2 we would use, then factor out
                 * common divisors before doing the work.
                 */
                int B2B5// powers of 2, 5 in bigB
                int     D2D5// powers of 2, 5 in bigD
                int Ulp2;   // powers of 2 in halfUlp.
                if ( exp >= 0 ){
                    B2 = B5 = 0;
                    D2 = D5 = exp;
                } else {
                    B2 = B5 = -exp;
                    D2 = D5 = 0;
                }
                if (  >= 0 ){
                    B2 += ;
                } else {
                    D2 -= ;
                }
                Ulp2 = B2;
                // shift bigB and bigD left by a number s. t.
                // halfUlp is still an integer.
                int hulpbias;
                if ( + <= -+1 ){
                    // This is going to be a denormalized number
                    // (if not actually zero).
                    // half an ULP is at 2^-(expBias+expShift+1)
                    hulpbias =  + ;
                } else {
                    hulpbias =  + 2 - ;
                }
                B2 += hulpbias;
                D2 += hulpbias;
                // if there are common factors of 2, we might just as well
                // factor them out, as they add nothing useful.
                int common2 = Math.minB2, Math.minD2Ulp2 ) );
                B2 -= common2;
                D2 -= common2;
                Ulp2 -= common2;
                // do multiplications by powers of 5 and 2
                bigB = multPow52bigBB5B2 );
                FDBigInt bigD = multPow52new FDBigIntbigD0 ), D5D2 );
                //
                // to recap:
                // bigB is the scaled-big-int version of our floating-point
                // candidate.
                // bigD is the scaled-big-int version of the exact value
                // as we understand it.
                // halfUlp is 1/2 an ulp of bigB, except for special cases
                // of exact powers of 2
                //
                // the plan is to compare bigB with bigD, and if the difference
                // is less than halfUlp, then we're satisfied. Otherwise,
                // use the ratio of difference to halfUlp to calculate a fudge
                // factor to add to the floating value, then go 'round again.
                //
                FDBigInt diff;
                int cmpResult;
                boolean overvalue;
                if ( (cmpResult = bigB.cmpbigD ) ) > 0 ){
                    overvalue = true// our candidate is too big.
                    diff = bigB.subbigD );
                    if ( ( == 1) && ( > -) ){
                        // candidate is a normalized exact power of 2 and
                        // is too big. We will be subtracting.
                        // For our purposes, ulp is the ulp of the
                        // next smaller range.
                        Ulp2 -= 1;
                        if ( Ulp2 < 0 ){
                            // rats. Cannot de-scale ulp this far.
                            // must scale diff in other direction.
                            Ulp2 = 0;
                            diff.lshiftMe( 1 );
                        }
                    }
                } else if ( cmpResult < 0 ){
                    overvalue = false// our candidate is too small.
                    diff = bigD.subbigB );
                } else {
                    // the candidate is exactly right!
                    // this happens with surprising fequency
                    break correctionLoop;
                }
                FDBigInt halfUlp = constructPow52B5Ulp2 );
                if ( (cmpResult = diff.cmphalfUlp ) ) < 0 ){
                    // difference is small.
                    // this is close enough
                    if () {
                         = overvalue ? -1 : 1;
                    }
                    break correctionLoop;
                } else if ( cmpResult == 0 ){
                    // difference is exactly half an ULP
                    // round to some other value maybe, then finish
                    dValue += 0.5*ulpdValueovervalue );
                    // should check for bigIntNBits == 1 here??
                    if () {
                         = overvalue ? -1 : 1;
                    }
                    break correctionLoop;
                } else {
                    // difference is non-trivial.
                    // could scale addend by ratio of difference to
                    // halfUlp here, if we bothered to compute that difference.
                    // Most of the time ( I hope ) it is about 1 anyway.
                    dValue += ulpdValueovervalue );
                    if ( dValue == 0.0 || dValue == . )
                        break correctionLoop; // oops. Fell off end of range.
                    continue// try again.
                }
            }
            return ()? -dValue : dValue;
        }
    }
    /*
     * Take a FormattedFloatingDecimal, which we presumably just scanned in,
     * and find out what its value is, as a float.
     * This is distinct from doubleValue() to avoid the extremely
     * unlikely case of a double rounding error, wherein the converstion
     * to double has one rounding error, and the conversion of that double
     * to a float has another rounding error, IN THE WRONG DIRECTION,
     * ( because of the preference to a zero low-order bit ).
     */
    public float
        floatValue(){
        int     kDigits = Math.min+1 );
        int     iValue;
        float   fValue;
        // First, check for NaN and Infinity values
        if( ==  ||  == ) {
            if( == )
                return .;
            else
                return (?.:.);
        }
        else {
            /*
             * convert the lead kDigits to an integer.
             */
            iValue = (int)[0]-(int)'0';
            for ( int i=1; i < kDigitsi++ ){
                iValue = iValue*10 + (int)[i]-(int)'0';
            }
            fValue = (float)iValue;
            int exp = -kDigits;
            /*
             * iValue now contains an integer with the value of
             * the first kDigits digits of the number.
             * fValue contains the (float) of the same.
             */
            if (  <=  ){
                /*
                 * possibly an easy case.
                 * We know that the digits can be represented
                 * exactly. And if the exponent isn't too outrageous,
                 * the whole thing can be done with one operation,
                 * thus one rounding error.
                 * Note that all our constructors trim all leading and
                 * trailing zeros, so simple values (including zero)
                 * will always end up here.
                 */
                if (exp == 0 || fValue == 0.0f)
                    return ()? -fValue : fValue// small floating integer
                else if ( exp >= 0 ){
                    if ( exp <=  ){
                        /*
                         * Can get the answer with one operation,
                         * thus one roundoff.
                         */
                        fValue *= [exp];
                        return ()? -fValue : fValue;
                    }
                    int slop =  - kDigits;
                    if ( exp <= +slop ){
                        /*
                         * We can multiply dValue by 10^(slop)
                         * and it is still "small" and exact.
                         * Then we can multiply by 10^(exp-slop)
                         * with one rounding.
                         */
                        fValue *= [slop];
                        fValue *= [exp-slop];
                        return ()? -fValue : fValue;
                    }
                    /*
                     * Else we have a hard case with a positive exp.
                     */
                } else {
                    if ( exp >= - ){
                        /*
                         * Can get the answer in one division.
                         */
                        fValue /= [-exp];
                        return ()? -fValue : fValue;
                    }
                    /*
                     * Else we have a hard case with a negative exp.
                     */
                }
            } else if ( ( >= ) && (+ <= ) ){
                /*
                 * In double-precision, this is an exact floating integer.
                 * So we can compute to double, then shorten to float
                 * with one round, and get the right answer.
                 *
                 * First, finish accumulating digits.
                 * Then convert that integer to a double, multiply
                 * by the appropriate power of ten, and convert to float.
                 */
                long lValue = (long)iValue;
                for ( int i=kDigitsi < i++ ){
                    lValue = lValue*10L + (long)((int)[i]-(int)'0');
                }
                double dValue = (double)lValue;
                exp = -;
                dValue *= [exp];
                fValue = (float)dValue;
                return ()? -fValue : fValue;
            }
            /*
             * Harder cases:
             * The sum of digits plus exponent is greater than
             * what we think we can do with one error.
             *
             * Start by weeding out obviously out-of-range
             * results, then convert to double and go to
             * common hard-case code.
             */
            if (  > +1 ){
                /*
                 * Lets face it. This is going to be
                 * Infinity. Cut to the chase.
                 */
                return ()? . : .;
            } else if (  < -1 ){
                /*
                 * Lets face it. This is going to be
                 * zero. Cut to the chase.
                 */
                return ()? -0.0f : 0.0f;
            }
            /*
             * Here, we do 'way too much work, but throwing away
             * our partial results, and going and doing the whole
             * thing as double, then throwing away half the bits that computes
             * when we convert back to float.
             *
             * The alternative is to reproduce the whole multiple-precision
             * algorythm for float precision, or to try to parameterize it
             * for common usage. The former will take about 400 lines of code,
             * and the latter I tried without success. Thus the semi-hack
             * answer here.
             */
             = !;
            double dValue = doubleValue();
            return stickyRounddValue );
        }
    }
    /*
     * All the positive powers of 10 that can be
     * represented exactly in double/float.
     */
    private static final double small10pow[] = {
        1.0e0,
        1.0e1, 1.0e2, 1.0e3, 1.0e4, 1.0e5,
        1.0e6, 1.0e7, 1.0e8, 1.0e9, 1.0e10,
        1.0e11, 1.0e12, 1.0e13, 1.0e14, 1.0e15,
        1.0e16, 1.0e17, 1.0e18, 1.0e19, 1.0e20,
        1.0e21, 1.0e22
    };
    private static final float singleSmall10pow[] = {
        1.0e0f,
        1.0e1f, 1.0e2f, 1.0e3f, 1.0e4f, 1.0e5f,
        1.0e6f, 1.0e7f, 1.0e8f, 1.0e9f, 1.0e10f
    };
    private static final double big10pow[] = {
        1e16, 1e32, 1e64, 1e128, 1e256 };
    private static final double tiny10pow[] = {
        1e-16, 1e-32, 1e-64, 1e-128, 1e-256 };
    private static final int maxSmallTen = .-1;
    private static final int singleMaxSmallTen = .-1;
    private static final int small5pow[] = {
        1,
        5,
        5*5,
        5*5*5,
        5*5*5*5,
        5*5*5*5*5,
        5*5*5*5*5*5,
        5*5*5*5*5*5*5,
        5*5*5*5*5*5*5*5,
        5*5*5*5*5*5*5*5*5,
        5*5*5*5*5*5*5*5*5*5,
        5*5*5*5*5*5*5*5*5*5*5,
        5*5*5*5*5*5*5*5*5*5*5*5,
        5*5*5*5*5*5*5*5*5*5*5*5*5
    };
    private static final long long5pow[] = {
        1L,
        5L,
        5L*5,
        5L*5*5,
        5L*5*5*5,
        5L*5*5*5*5,
        5L*5*5*5*5*5,
        5L*5*5*5*5*5*5,
        5L*5*5*5*5*5*5*5,
        5L*5*5*5*5*5*5*5*5,
        5L*5*5*5*5*5*5*5*5*5,
        5L*5*5*5*5*5*5*5*5*5*5,
        5L*5*5*5*5*5*5*5*5*5*5*5,
        5L*5*5*5*5*5*5*5*5*5*5*5*5,
        5L*5*5*5*5*5*5*5*5*5*5*5*5*5,
        5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
        5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
        5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
        5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
        5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
        5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
        5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
        5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
        5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
        5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
        5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
        5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
    };
    // approximately ceil( log2( long5pow[i] ) )
    private static final int n5bits[] = {
        0,
        3,
        5,
        7,
        10,
        12,
        14,
        17,
        19,
        21,
        24,
        26,
        28,
        31,
        33,
        35,
        38,
        40,
        42,
        45,
        47,
        49,
        52,
        54,
        56,
        59,
        61,
    };
    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.
     */
        // Verify string is a member of the hexadecimal floating-point
        // string language.
        Matcher m = .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 ?
                                                   . : 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(significandStringi);
                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(significandStringi);
                // 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 > .) {         // Infinite result
                // overflow to properly signed infinity
                return new FormattedFloatingDecimal(sign * .);
            } else {  // Finite return value
                if (exponent <= . && // (Usually) normal result
                    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).) <<
                                     (.-1))
                                   & .) |
                        (. & significand);
                }  else  {  // Subnormal or zero
                    // (exponent < DoubleConsts.MIN_EXPONENT)
                    if (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 - . + 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)(. -1) + // subnorm exp.
                                          (long).) <<
                                         (.-1))
                                       & .) |
                            (. & 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 >= .-1) &&
                    (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.
                        ifround || 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 s with any leading zeros removed.
    static String stripLeadingZeros(String s) {
        return  s.replaceFirst("^0+""");
    }

    
Extract a hexadecimal digit from position position of string s.
    static int getHexDigit(String sint 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;
    }
New to GrepCode? Check out our FAQ X