/*
 * Copyright (c) 1996, 2013, Oracle and/or its affiliates. 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.misc;

import java.util.Arrays;
import java.util.regex.*;

/**
 * A class for converting between ASCII and decimal representations of a single
 * or double precision floating point number. Most conversions are provided via
 * static convenience methods, although a <code>BinaryToASCIIConverter</code>
 * instance may be obtained and reused.
 */
public class FloatingDecimal{
    //
    // Constants of the implementation;
    // most are IEEE-754 related.
    // (There are more really boring constants at the end.)
    //
    static final int    EXP_SHIFT = DoubleConsts.SIGNIFICAND_WIDTH - 1;
    static final long   FRACT_HOB = ( 1L<<EXP_SHIFT ); // assumed High-Order bit
    static final long   EXP_ONE   = ((long)DoubleConsts.EXP_BIAS)<<EXP_SHIFT; // exponent of 1.0
    static final int    MAX_SMALL_BIN_EXP = 62;
    static final int    MIN_SMALL_BIN_EXP = -( 63 / 3 );
    static final int    MAX_DECIMAL_DIGITS = 15;
    static final int    MAX_DECIMAL_EXPONENT = 308;
    static final int    MIN_DECIMAL_EXPONENT = -324;
    static final int    BIG_DECIMAL_EXPONENT = 324; // i.e. abs(MIN_DECIMAL_EXPONENT)
    static final int    MAX_NDIGITS = 1100;

    static final int    SINGLE_EXP_SHIFT  =   FloatConsts.SIGNIFICAND_WIDTH - 1;
    static final int    SINGLE_FRACT_HOB  =   1<<SINGLE_EXP_SHIFT;
    static final int    SINGLE_MAX_DECIMAL_DIGITS = 7;
    static final int    SINGLE_MAX_DECIMAL_EXPONENT = 38;
    static final int    SINGLE_MIN_DECIMAL_EXPONENT = -45;
    static final int    SINGLE_MAX_NDIGITS = 200;

    static final int    INT_DECIMAL_DIGITS = 9;

    /**
     * Converts a double precision floating point value to a <code>String</code>.
     *
     * @param d The double precision value.
     * @return The value converted to a <code>String</code>.
     */
    public static String toJavaFormatString(double d) {
        return getBinaryToASCIIConverter(d).toJavaFormatString();
    }

    /**
     * Converts a single precision floating point value to a <code>String</code>.
     *
     * @param f The single precision value.
     * @return The value converted to a <code>String</code>.
     */
    public static String toJavaFormatString(float f) {
        return getBinaryToASCIIConverter(f).toJavaFormatString();
    }

    /**
     * Appends a double precision floating point value to an <code>Appendable</code>.
     * @param d The double precision value.
     * @param buf The <code>Appendable</code> with the value appended.
     */
    public static void appendTo(double d, Appendable buf) {
        getBinaryToASCIIConverter(d).appendTo(buf);
    }

    /**
     * Appends a single precision floating point value to an <code>Appendable</code>.
     * @param f The single precision value.
     * @param buf The <code>Appendable</code> with the value appended.
     */
    public static void appendTo(float f, Appendable buf) {
        getBinaryToASCIIConverter(f).appendTo(buf);
    }

    /**
     * Converts a <code>String</code> to a double precision floating point value.
     *
     * @param s The <code>String</code> to convert.
     * @return The double precision value.
     * @throws NumberFormatException If the <code>String</code> does not
     * represent a properly formatted double precision value.
     */
    public static double parseDouble(String s) throws NumberFormatException {
        return readJavaFormatString(s).doubleValue();
    }

    /**
     * Converts a <code>String</code> to a single precision floating point value.
     *
     * @param s The <code>String</code> to convert.
     * @return The single precision value.
     * @throws NumberFormatException If the <code>String</code> does not
     * represent a properly formatted single precision value.
     */
    public static float parseFloat(String s) throws NumberFormatException {
        return readJavaFormatString(s).floatValue();
    }

    /**
     * A converter which can process single or double precision floating point
     * values into an ASCII <code>String</code> representation.
     */
    public interface BinaryToASCIIConverter {
        /**
         * Converts a floating point value into an ASCII <code>String</code>.
         * @return The value converted to a <code>String</code>.
         */
        public String toJavaFormatString();

        /**
         * Appends a floating point value to an <code>Appendable</code>.
         * @param buf The <code>Appendable</code> to receive the value.
         */
        public void appendTo(Appendable buf);

        /**
         * Retrieves the decimal exponent most closely corresponding to this value.
         * @return The decimal exponent.
         */
        public int getDecimalExponent();

        /**
         * Retrieves the value as an array of digits.
         * @param digits The digit array.
         * @return The number of valid digits copied into the array.
         */
        public int getDigits(char[] digits);

        /**
         * Indicates the sign of the value.
         * @return <code>value < 0.0</code>.
         */
        public boolean isNegative();

        /**
         * Indicates whether the value is either infinite or not a number.
         *
         * @return <code>true</code> if and only if the value is <code>NaN</code>
         * or infinite.
         */
        public boolean isExceptional();

        /**
         * Indicates whether the value was rounded up during the binary to ASCII
         * conversion.
         *
         * @return <code>true</code> if and only if the value was rounded up.
         */
        public boolean digitsRoundedUp();

        /**
         * Indicates whether the binary to ASCII conversion was exact.
         *
         * @return <code>true</code> if any only if the conversion was exact.
         */
        public boolean decimalDigitsExact();
    }

    /**
     * A <code>BinaryToASCIIConverter</code> which represents <code>NaN</code>
     * and infinite values.
     */
    private static class ExceptionalBinaryToASCIIBuffer implements BinaryToASCIIConverter {
        final private String image;
        private boolean isNegative;

        public ExceptionalBinaryToASCIIBuffer(String image, boolean isNegative) {
            this.image = image;
            this.isNegative = isNegative;
        }

        @Override
        public String toJavaFormatString() {
            return image;
        }

        @Override
        public void appendTo(Appendable buf) {
            if (buf instanceof StringBuilder) {
                ((StringBuilder) buf).append(image);
            } else if (buf instanceof StringBuffer) {
                ((StringBuffer) buf).append(image);
            } else {
                assert false;
            }
        }

        @Override
        public int getDecimalExponent() {
            throw new IllegalArgumentException("Exceptional value does not have an exponent");
        }

        @Override
        public int getDigits(char[] digits) {
            throw new IllegalArgumentException("Exceptional value does not have digits");
        }

        @Override
        public boolean isNegative() {
            return isNegative;
        }

        @Override
        public boolean isExceptional() {
            return true;
        }

        @Override
        public boolean digitsRoundedUp() {
            throw new IllegalArgumentException("Exceptional value is not rounded");
        }

        @Override
        public boolean decimalDigitsExact() {
            throw new IllegalArgumentException("Exceptional value is not exact");
        }
    }

    private static final String INFINITY_REP = "Infinity";
    private static final int INFINITY_LENGTH = INFINITY_REP.length();
    private static final String NAN_REP = "NaN";
    private static final int NAN_LENGTH = NAN_REP.length();

    private static final BinaryToASCIIConverter B2AC_POSITIVE_INFINITY = new ExceptionalBinaryToASCIIBuffer(INFINITY_REP, false);
    private static final BinaryToASCIIConverter B2AC_NEGATIVE_INFINITY = new ExceptionalBinaryToASCIIBuffer("-" + INFINITY_REP, true);
    private static final BinaryToASCIIConverter B2AC_NOT_A_NUMBER = new ExceptionalBinaryToASCIIBuffer(NAN_REP, false);
    private static final BinaryToASCIIConverter B2AC_POSITIVE_ZERO = new BinaryToASCIIBuffer(false, new char[]{'0'});
    private static final BinaryToASCIIConverter B2AC_NEGATIVE_ZERO = new BinaryToASCIIBuffer(true,  new char[]{'0'});

    /**
     * A buffered implementation of <code>BinaryToASCIIConverter</code>.
     */
    static class BinaryToASCIIBuffer implements BinaryToASCIIConverter {
        private boolean isNegative;
        private int decExponent;
        private int firstDigitIndex;
        private int nDigits;
        private final char[] digits;
        private final char[] buffer = new char[26];

        //
        // The fields below provide additional information about the result of
        // the binary to decimal digits conversion done in dtoa() and roundup()
        // methods. They are changed if needed by those two methods.
        //

        // True if the dtoa() binary to decimal conversion was exact.
        private boolean exactDecimalConversion = false;

        // True if the result of the binary to decimal conversion was rounded-up
        // at the end of the conversion process, i.e. roundUp() method was called.
        private boolean decimalDigitsRoundedUp = false;

        /**
         * Default constructor; used for non-zero values,
         * <code>BinaryToASCIIBuffer</code> may be thread-local and reused
         */
        BinaryToASCIIBuffer(){
            this.digits = new char[20];
        }

        /**
         * Creates a specialized value (positive and negative zeros).
         */
        BinaryToASCIIBuffer(boolean isNegative, char[] digits){
            this.isNegative = isNegative;
            this.decExponent  = 0;
            this.digits = digits;
            this.firstDigitIndex = 0;
            this.nDigits = digits.length;
        }

        @Override
        public String toJavaFormatString() {
            int len = getChars(buffer);
            return new String(buffer, 0, len);
        }

        @Override
        public void appendTo(Appendable buf) {
            int len = getChars(buffer);
            if (buf instanceof StringBuilder) {
                ((StringBuilder) buf).append(buffer, 0, len);
            } else if (buf instanceof StringBuffer) {
                ((StringBuffer) buf).append(buffer, 0, len);
            } else {
                assert false;
            }
        }

        @Override
        public int getDecimalExponent() {
            return decExponent;
        }

        @Override
        public int getDigits(char[] digits) {
            System.arraycopy(this.digits,firstDigitIndex,digits,0,this.nDigits);
            return this.nDigits;
        }

        @Override
        public boolean isNegative() {
            return isNegative;
        }

        @Override
        public boolean isExceptional() {
            return false;
        }

        @Override
        public boolean digitsRoundedUp() {
            return decimalDigitsRoundedUp;
        }

        @Override
        public boolean decimalDigitsExact() {
            return exactDecimalConversion;
        }

        private void setSign(boolean isNegative) {
            this.isNegative = isNegative;
        }

        /**
         * 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 developLongDigits( int decExponent, long lvalue, int insignificantDigits ){
            if ( insignificantDigits != 0 ){
                // Discard non-significant low-order bits, while rounding,
                // up to insignificant value.
                long pow10 = FDBigInteger.LONG_5_POW[insignificantDigits] << insignificantDigits; // 10^i == 5^i * 2^i;
                long residue = lvalue % pow10;
                lvalue /= pow10;
                decExponent += insignificantDigits;
                if ( residue >= (pow10>>1) ){
                    // round up based on the low-order bits we're discarding
                    lvalue++;
                }
            }
            int  digitno = digits.length -1;
            int  c;
            if ( lvalue <= Integer.MAX_VALUE ){
                assert lvalue > 0L : lvalue; // lvalue <= 0
                // even easier subcase!
                // can do int arithmetic rather than long!
                int  ivalue = (int)lvalue;
                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.
                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');
            }
            this.decExponent = decExponent+1;
            this.firstDigitIndex = digitno;
            this.nDigits = this.digits.length - digitno;
        }

        private void dtoa( int binExp, long fractBits, int nSignificantBits, boolean isCompatibleFormat)
        {
            assert fractBits > 0 ; // fractBits here can't be zero or negative
            assert (fractBits & FRACT_HOB)!=0  ; // Hi-order bit should be set
            // 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.
            final int tailZeros = Long.numberOfTrailingZeros(fractBits);

            // number of significant bits of fractBits;
            final int nFractBits = EXP_SHIFT+1-tailZeros;

            // reset flags to default values as dtoa() does not always set these
            // flags and a prior call to dtoa() might have set them to incorrect
            // values with respect to the current state.
            decimalDigitsRoundedUp = false;
            exactDecimalConversion = false;

            // number of significant bits to the right of the point.
            int nTinyBits = Math.max( 0, nFractBits - binExp - 1 );
            if ( binExp <= MAX_SMALL_BIN_EXP && binExp >= MIN_SMALL_BIN_EXP ){
                // Look more closely at the number to decide if,
                // with scaling by 10^nTinyBits, the result will fit in
                // a long.
                if ( (nTinyBits < FDBigInteger.LONG_5_POW.length) && ((nFractBits + N_5_BITS[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 EXP_SHIFT-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.
                    //
                    if ( nTinyBits == 0 ) {
                        int insignificant;
                        if ( binExp > nSignificantBits ){
                            insignificant = insignificantDigitsForPow2(binExp-nSignificantBits-1);
                        } else {
                            insignificant = 0;
                        }
                        if ( binExp >= EXP_SHIFT ){
                            fractBits <<= (binExp-EXP_SHIFT);
                        } else {
                            fractBits >>>= (EXP_SHIFT-binExp) ;
                        }
                        developLongDigits( 0, fractBits, insignificant );
                        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 >>>= EXP_SHIFT+1-nFractBits;
                    //     fractBits//= long5pow[ nTinyBits ];
                    //     halfULP = long5pow[ nTinyBits ] >> (1+nSignificantBits-nFractBits);
                    //     developLongDigits( -nTinyBits, fractBits, insignificantDigits(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.
            //
            int decExp = estimateDecExp(fractBits,binExp);
            int B2, B5; // powers of 2 and powers of 5, respectively, in B
            int S2, S5; // powers of 2 and powers of 5, respectively, in S
            int M2, M5; // powers of 2 and powers of 5, respectively, in M

            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 (EXP_SHIFT+1-nFractBits) zeros. In the interest of compactness,
            // I will shift out those zeros before turning fractBits into a
            // FDBigInteger. The resulting whole number will be
            //      d * 2^(nFractBits-1-binExp).
            //
            fractBits >>>= tailZeros;
            B2 -= nFractBits-1;
            int common2factor = Math.min( B2, S2 );
            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 asymmetry 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.
            //
            int ndigit = 0;
            boolean low, high;
            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 FDBigInteger arithmetic.
            // We use the same algorithms, except that we "normalize"
            // our FDBigIntegers 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 asymmetry 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.
            //
            // binary digits needed to represent B, approx.
            int Bbits = nFractBits + B2 + (( B5 < N_5_BITS.length )? N_5_BITS[B5] : ( B5*3 ));

            // binary digits needed to represent 10*S, approx.
            int tenSbits = S2+1 + (( (S5+1) < N_5_BITS.length )? N_5_BITS[(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 * FDBigInteger.SMALL_5_POW[B5] ) << B2;
                    int s = FDBigInteger.SMALL_5_POW[S5] << S2;
                    int m = FDBigInteger.SMALL_5_POW[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 ( !isCompatibleFormat ||decExp < -3 || 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;
                    exactDecimalConversion  = (b == 0);
                } else {
                    // still good! they're all longs!
                    long b = (fractBits * FDBigInteger.LONG_5_POW[B5] ) << B2;
                    long s = FDBigInteger.LONG_5_POW[S5] << S2;
                    long m = FDBigInteger.LONG_5_POW[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 ( !isCompatibleFormat || decExp < -3 || 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;
                    exactDecimalConversion  = (b == 0);
                }
            } else {
                //
                // We really must do FDBigInteger arithmetic.
                // Fist, construct our FDBigInteger initial values.
                //
                FDBigInteger Sval = FDBigInteger.valueOfPow52(S5, S2);
                int shiftBias = Sval.getNormalizationBias();
                Sval = Sval.leftShift(shiftBias); // normalize so that division works better

                FDBigInteger Bval = FDBigInteger.valueOfMulPow52(fractBits, B5, B2 + shiftBias);
                FDBigInteger Mval = FDBigInteger.valueOfPow52(M5 + 1, M2 + shiftBias + 1);

                FDBigInteger tenSval = FDBigInteger.valueOfPow52(S5 + 1, S2 + shiftBias + 1); //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.quoRemIteration( Sval );
                low  = (Bval.cmp( Mval ) < 0);
                high = tenSval.addAndCmp(Bval,Mval)<=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 (!isCompatibleFormat || decExp < -3 || decExp >= 8 ){
                    high = low = false;
                }
                while( ! low && ! high ){
                    q = Bval.quoRemIteration( Sval );
                    assert q < 10 : q;  // excessively large digit
                    Mval = Mval.multBy10(); //Mval = Mval.mult( 10 );
                    low  = (Bval.cmp( Mval ) < 0);
                    high = tenSval.addAndCmp(Bval,Mval)<=0;
                    digits[ndigit++] = (char)('0' + q);
                }
                if ( high && low ){
                    Bval = Bval.leftShift(1);
                    lowDigitDifference = Bval.cmp(tenSval);
                } else {
                    lowDigitDifference = 0L; // this here only for flow analysis!
                }
                exactDecimalConversion  = (Bval.cmp( FDBigInteger.ZERO ) == 0);
            }
            this.decExponent = decExp+1;
            this.firstDigitIndex = 0;
            this.nDigits = 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[firstDigitIndex+nDigits-1]&1) != 0 ) {
                            roundup();
                        }
                    } else if ( lowDigitDifference > 0 ){
                        roundup();
                    }
                } else {
                    roundup();
                }
            }
        }

        // 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 = (firstDigitIndex + nDigits - 1);
            int q = digits[i];
            if (q == '9') {
                while (q == '9' && i > firstDigitIndex) {
                    digits[i] = '0';
                    q = digits[--i];
                }
                if (q == '9') {
                    // carryout! High-order 1, rest 0s, larger exp.
                    decExponent += 1;
                    digits[firstDigitIndex] = '1';
                    return;
                }
                // else fall through.
            }
            digits[i] = (char) (q + 1);
            decimalDigitsRoundedUp = true;
        }

        /**
         * 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.
         */
        static int estimateDecExp(long fractBits, int binExp) {
            double d2 = Double.longBitsToDouble( EXP_ONE | ( fractBits & DoubleConsts.SIGNIF_BIT_MASK ) );
            double d = (d2-1.5D)*0.289529654D + 0.176091259 + (double)binExp * 0.301029995663981;
            long dBits = Double.doubleToRawLongBits(d);  //can't be NaN here so use raw
            int exponent = (int)((dBits & DoubleConsts.EXP_BIT_MASK) >> EXP_SHIFT) - DoubleConsts.EXP_BIAS;
            boolean isNegative = (dBits & DoubleConsts.SIGN_BIT_MASK) != 0; // discover sign
            if(exponent>=0 && exponent<52) { // hot path
                long mask   = DoubleConsts.SIGNIF_BIT_MASK >> exponent;
                int r = (int)(( (dBits&DoubleConsts.SIGNIF_BIT_MASK) | FRACT_HOB )>>(EXP_SHIFT-exponent));
                return isNegative ? (((mask & dBits) == 0L ) ? -r : -r-1 ) : r;
            } else if (exponent < 0) {
                return (((dBits&~DoubleConsts.SIGN_BIT_MASK) == 0) ? 0 :
                        ( (isNegative) ? -1 : 0) );
            } else { //if (exponent >= 52)
                return (int)d;
            }
        }

        private static int insignificantDigits(int insignificant) {
            int i;
            for ( i = 0; insignificant >= 10L; i++ ) {
                insignificant /= 10L;
            }
            return i;
        }

        /**
         * Calculates
         * <pre>
         * insignificantDigitsForPow2(v) == insignificantDigits(1L<<v)
         * </pre>
         */
        private static int insignificantDigitsForPow2(int p2) {
            if(p2>1 && p2 < insignificantDigitsNumber.length) {
                return insignificantDigitsNumber[p2];
            }
            return 0;
        }

        /**
         *  If insignificant==(1L << ixd)
         *  i = insignificantDigitsNumber[idx] is the same as:
         *  int i;
         *  for ( i = 0; insignificant >= 10L; i++ )
         *         insignificant /= 10L;
         */
        private static int[] insignificantDigitsNumber = {
            0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3,
            4, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7,
            8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 11, 11, 11,
            12, 12, 12, 12, 13, 13, 13, 14, 14, 14,
            15, 15, 15, 15, 16, 16, 16, 17, 17, 17,
            18, 18, 18, 19
        };

        // approximately ceil( log2( long5pow[i] ) )
        private static final int[] N_5_BITS = {
                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 int getChars(char[] result) {
            assert nDigits <= 19 : nDigits; // generous bound on size of nDigits
            int i = 0;
            if (isNegative) {
                result[0] = '-';
                i = 1;
            }
            if (decExponent > 0 && decExponent < 8) {
                // print digits.digits.
                int charLength = Math.min(nDigits, decExponent);
                System.arraycopy(digits, firstDigitIndex, result, i, charLength);
                i += charLength;
                if (charLength < decExponent) {
                    charLength = decExponent - charLength;
                    Arrays.fill(result,i,i+charLength,'0');
                    i += charLength;
                    result[i++] = '.';
                    result[i++] = '0';
                } else {
                    result[i++] = '.';
                    if (charLength < nDigits) {
                        int t = nDigits - charLength;
                        System.arraycopy(digits, firstDigitIndex+charLength, result, i, t);
                        i += t;
                    } else {
                        result[i++] = '0';
                    }
                }
            } else if (decExponent <= 0 && decExponent > -3) {
                result[i++] = '0';
                result[i++] = '.';
                if (decExponent != 0) {
                    Arrays.fill(result, i, i-decExponent, '0');
                    i -= decExponent;
                }
                System.arraycopy(digits, firstDigitIndex, result, i, nDigits);
                i += nDigits;
            } else {
                result[i++] = digits[firstDigitIndex];
                result[i++] = '.';
                if (nDigits > 1) {
                    System.arraycopy(digits, firstDigitIndex+1, result, i, nDigits - 1);
                    i += nDigits - 1;
                } else {
                    result[i++] = '0';
                }
                result[i++] = 'E';
                int e;
                if (decExponent <= 0) {
                    result[i++] = '-';
                    e = -decExponent + 1;
                } else {
                    e = decExponent - 1;
                }
                // decExponent has 1, 2, or 3, digits
                if (e <= 9) {
                    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;
        }

    }

    private static final ThreadLocal<BinaryToASCIIBuffer> threadLocalBinaryToASCIIBuffer =
            new ThreadLocal<BinaryToASCIIBuffer>() {
                @Override
                protected BinaryToASCIIBuffer initialValue() {
                    return new BinaryToASCIIBuffer();
                }
            };

    private static BinaryToASCIIBuffer getBinaryToASCIIBuffer() {
        return threadLocalBinaryToASCIIBuffer.get();
    }

    /**
     * A converter which can process an ASCII <code>String</code> representation
     * of a single or double precision floating point value into a
     * <code>float</code> or a <code>double</code>.
     */
    interface ASCIIToBinaryConverter {

        double doubleValue();

        float floatValue();

    }

    /**
     * A <code>ASCIIToBinaryConverter</code> container for a <code>double</code>.
     */
    static class PreparedASCIIToBinaryBuffer implements ASCIIToBinaryConverter {
        final private double doubleVal;
        final private float floatVal;

        public PreparedASCIIToBinaryBuffer(double doubleVal, float floatVal) {
            this.doubleVal = doubleVal;
            this.floatVal = floatVal;
        }

        @Override
        public double doubleValue() {
            return doubleVal;
        }

        @Override
        public float floatValue() {
            return floatVal;
        }
    }

    static final ASCIIToBinaryConverter A2BC_POSITIVE_INFINITY = new PreparedASCIIToBinaryBuffer(Double.POSITIVE_INFINITY, Float.POSITIVE_INFINITY);
    static final ASCIIToBinaryConverter A2BC_NEGATIVE_INFINITY = new PreparedASCIIToBinaryBuffer(Double.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY);
    static final ASCIIToBinaryConverter A2BC_NOT_A_NUMBER  = new PreparedASCIIToBinaryBuffer(Double.NaN, Float.NaN);
    static final ASCIIToBinaryConverter A2BC_POSITIVE_ZERO = new PreparedASCIIToBinaryBuffer(0.0d, 0.0f);
    static final ASCIIToBinaryConverter A2BC_NEGATIVE_ZERO = new PreparedASCIIToBinaryBuffer(-0.0d, -0.0f);

    /**
     * A buffered implementation of <code>ASCIIToBinaryConverter</code>.
     */
    static class ASCIIToBinaryBuffer implements ASCIIToBinaryConverter {
        boolean     isNegative;
        int         decExponent;
        char        digits[];
        int         nDigits;

        ASCIIToBinaryBuffer( boolean negSign, int decExponent, char[] digits, int n)
        {
            this.isNegative = negSign;
            this.decExponent = decExponent;
            this.digits = digits;
            this.nDigits = n;
        }

        /**
         * Takes a FloatingDecimal, which we presumably just scanned in,
         * and finds 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.
         */
        @Override
        public double doubleValue() {
            int kDigits = Math.min(nDigits, MAX_DECIMAL_DIGITS + 1);
            //
            // convert the lead kDigits to a long integer.
            //
            // (special performance hack: start to do it using int)
            int iValue = (int) digits[0] - (int) '0';
            int iDigits = Math.min(kDigits, INT_DECIMAL_DIGITS);
            for (int i = 1; i < iDigits; i++) {
                iValue = iValue * 10 + (int) digits[i] - (int) '0';
            }
            long lValue = (long) iValue;
            for (int i = iDigits; i < kDigits; i++) {
                lValue = lValue * 10L + (long) ((int) digits[i] - (int) '0');
            }
            double dValue = (double) lValue;
            int exp = decExponent - 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 (nDigits <= MAX_DECIMAL_DIGITS) {
                //
                // 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 (isNegative) ? -dValue : dValue; // small floating integer
                }
                else if (exp >= 0) {
                    if (exp <= MAX_SMALL_TEN) {
                        //
                        // Can get the answer with one operation,
                        // thus one roundoff.
                        //
                        double rValue = dValue * SMALL_10_POW[exp];
                        return (isNegative) ? -rValue : rValue;
                    }
                    int slop = MAX_DECIMAL_DIGITS - kDigits;
                    if (exp <= MAX_SMALL_TEN + 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 *= SMALL_10_POW[slop];
                        double rValue = dValue * SMALL_10_POW[exp - slop];
                        return (isNegative) ? -rValue : rValue;
                    }
                    //
                    // Else we have a hard case with a positive exp.
                    //
                } else {
                    if (exp >= -MAX_SMALL_TEN) {
                        //
                        // Can get the answer in one division.
                        //
                        double rValue = dValue / SMALL_10_POW[-exp];
                        return (isNegative) ? -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 (decExponent > MAX_DECIMAL_EXPONENT + 1) {
                    //
                    // Lets face it. This is going to be
                    // Infinity. Cut to the chase.
                    //
                    return (isNegative) ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
                }
                if ((exp & 15) != 0) {
                    dValue *= SMALL_10_POW[exp & 15];
                }
                if ((exp >>= 4) != 0) {
                    int j;
                    for (j = 0; exp > 1; j++, exp >>= 1) {
                        if ((exp & 1) != 0) {
                            dValue *= BIG_10_POW[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 * BIG_10_POW[j];
                    if (Double.isInfinite(t)) {
                        //
                        // 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 *= BIG_10_POW[j];
                        if (Double.isInfinite(t)) {
                            return (isNegative) ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
                        }
                        t = Double.MAX_VALUE;
                    }
                    dValue = t;
                }
            } else if (exp < 0) {
                exp = -exp;
                if (decExponent < MIN_DECIMAL_EXPONENT - 1) {
                    //
                    // Lets face it. This is going to be
                    // zero. Cut to the chase.
                    //
                    return (isNegative) ? -0.0 : 0.0;
                }
                if ((exp & 15) != 0) {
                    dValue /= SMALL_10_POW[exp & 15];
                }
                if ((exp >>= 4) != 0) {
                    int j;
                    for (j = 0; exp > 1; j++, exp >>= 1) {
                        if ((exp & 1) != 0) {
                            dValue *= TINY_10_POW[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 * TINY_10_POW[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 *= TINY_10_POW[j];
                        if (t == 0.0) {
                            return (isNegative) ? -0.0 : 0.0;
                        }
                        t = Double.MIN_VALUE;
                    }
                    dValue = t;
                }
            }

            //
            // dValue is now approximately the result.
            // The hard part is adjusting it, by comparison
            // with FDBigInteger arithmetic.
            // Formulate the EXACT big-number result as
            // bigD0 * 10^exp
            //
            if (nDigits > MAX_NDIGITS) {
                nDigits = MAX_NDIGITS + 1;
                digits[MAX_NDIGITS] = '1';
            }
            FDBigInteger bigD0 = new FDBigInteger(lValue, digits, kDigits, nDigits);
            exp = decExponent - nDigits;

            long ieeeBits = Double.doubleToRawLongBits(dValue); // IEEE-754 bits of double candidate
            final int B5 = Math.max(0, -exp); // powers of 5 in bigB, value is not modified inside correctionLoop
            final int D5 = Math.max(0, exp); // powers of 5 in bigD, value is not modified inside correctionLoop
            bigD0 = bigD0.multByPow52(D5, 0);
            bigD0.makeImmutable();   // prevent bigD0 modification inside correctionLoop
            FDBigInteger bigD = null;
            int prevD2 = 0;

            correctionLoop:
            while (true) {
                // here ieeeBits can't be NaN, Infinity or zero
                int binexp = (int) (ieeeBits >>> EXP_SHIFT);
                long bigBbits = ieeeBits & DoubleConsts.SIGNIF_BIT_MASK;
                if (binexp > 0) {
                    bigBbits |= FRACT_HOB;
                } else { // Normalize denormalized numbers.
                    assert bigBbits != 0L : bigBbits; // doubleToBigInt(0.0)
                    int leadingZeros = Long.numberOfLeadingZeros(bigBbits);
                    int shift = leadingZeros - (63 - EXP_SHIFT);
                    bigBbits <<= shift;
                    binexp = 1 - shift;
                }
                binexp -= DoubleConsts.EXP_BIAS;
                int lowOrderZeros = Long.numberOfTrailingZeros(bigBbits);
                bigBbits >>>= lowOrderZeros;
                final int bigIntExp = binexp - EXP_SHIFT + lowOrderZeros;
                final int bigIntNBits = EXP_SHIFT + 1 - lowOrderZeros;

                //
                // Scale bigD, bigB appropriately for
                // big-integer operations.
                // Naively, we multiply 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 B2 = B5; // powers of 2 in bigB
                int D2 = D5; // powers of 2 in bigD
                int Ulp2;   // powers of 2 in halfUlp.
                if (bigIntExp >= 0) {
                    B2 += bigIntExp;
                } else {
                    D2 -= bigIntExp;
                }
                Ulp2 = B2;
                // shift bigB and bigD left by a number s. t.
                // halfUlp is still an integer.
                int hulpbias;
                if (binexp <= -DoubleConsts.EXP_BIAS) {
                    // This is going to be a denormalized number
                    // (if not actually zero).
                    // half an ULP is at 2^-(DoubleConsts.EXP_BIAS+EXP_SHIFT+1)
                    hulpbias = binexp + lowOrderZeros + DoubleConsts.EXP_BIAS;
                } else {
                    hulpbias = 1 + lowOrderZeros;
                }
                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.min(B2, Math.min(D2, Ulp2));
                B2 -= common2;
                D2 -= common2;
                Ulp2 -= common2;
                // do multiplications by powers of 5 and 2
                FDBigInteger bigB = FDBigInteger.valueOfMulPow52(bigBbits, B5, B2);
                if (bigD == null || prevD2 != D2) {
                    bigD = bigD0.leftShift(D2);
                    prevD2 = D2;
                }
                //
                // 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.
                //
                FDBigInteger diff;
                int cmpResult;
                boolean overvalue;
                if ((cmpResult = bigB.cmp(bigD)) > 0) {
                    overvalue = true; // our candidate is too big.
                    diff = bigB.leftInplaceSub(bigD); // bigB is not user further - reuse
                    if ((bigIntNBits == 1) && (bigIntExp > -DoubleConsts.EXP_BIAS + 1)) {
                        // candidate is a normalized exact power of 2 and
                        // is too big (larger than Double.MIN_NORMAL). 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 = diff.leftShift(1);
                        }
                    }
                } else if (cmpResult < 0) {
                    overvalue = false; // our candidate is too small.
                    diff = bigD.rightInplaceSub(bigB); // bigB is not user further - reuse
                } else {
                    // the candidate is exactly right!
                    // this happens with surprising frequency
                    break correctionLoop;
                }
                cmpResult = diff.cmpPow52(B5, Ulp2);
                if ((cmpResult) < 0) {
                    // difference is small.
                    // this is close enough
                    break correctionLoop;
                } else if (cmpResult == 0) {
                    // difference is exactly half an ULP
                    // round to some other value maybe, then finish
                    if ((ieeeBits & 1) != 0) { // half ties to even
                        ieeeBits += overvalue ? -1 : 1; // nextDown or nextUp
                    }
                    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.
                    ieeeBits += overvalue ? -1 : 1; // nextDown or nextUp
                    if (ieeeBits == 0 || ieeeBits == DoubleConsts.EXP_BIT_MASK) { // 0.0 or Double.POSITIVE_INFINITY
                        break correctionLoop; // oops. Fell off end of range.
                    }
                    continue; // try again.
                }

            }
            if (isNegative) {
                ieeeBits |= DoubleConsts.SIGN_BIT_MASK;
            }
            return Double.longBitsToDouble(ieeeBits);
        }

        /**
         * Takes a FloatingDecimal, which we presumably just scanned in,
         * and finds 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 conversion
         * 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 ).
         */
        @Override
        public float floatValue() {
            int kDigits = Math.min(nDigits, SINGLE_MAX_DECIMAL_DIGITS + 1);
            //
            // convert the lead kDigits to an integer.
            //
            int iValue = (int) digits[0] - (int) '0';
            for (int i = 1; i < kDigits; i++) {
                iValue = iValue * 10 + (int) digits[i] - (int) '0';
            }
            float fValue = (float) iValue;
            int exp = decExponent - 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 (nDigits <= SINGLE_MAX_DECIMAL_DIGITS) {
                //
                // 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 (isNegative) ? -fValue : fValue; // small floating integer
                } else if (exp >= 0) {
                    if (exp <= SINGLE_MAX_SMALL_TEN) {
                        //
                        // Can get the answer with one operation,
                        // thus one roundoff.
                        //
                        fValue *= SINGLE_SMALL_10_POW[exp];
                        return (isNegative) ? -fValue : fValue;
                    }
                    int slop = SINGLE_MAX_DECIMAL_DIGITS - kDigits;
                    if (exp <= SINGLE_MAX_SMALL_TEN + slop) {
                        //
                        // We can multiply fValue by 10^(slop)
                        // and it is still "small" and exact.
                        // Then we can multiply by 10^(exp-slop)
                        // with one rounding.
                        //
                        fValue *= SINGLE_SMALL_10_POW[slop];
                        fValue *= SINGLE_SMALL_10_POW[exp - slop];
                        return (isNegative) ? -fValue : fValue;
                    }
                    //
                    // Else we have a hard case with a positive exp.
                    //
                } else {
                    if (exp >= -SINGLE_MAX_SMALL_TEN) {
                        //
                        // Can get the answer in one division.
                        //
                        fValue /= SINGLE_SMALL_10_POW[-exp];
                        return (isNegative) ? -fValue : fValue;
                    }
                    //
                    // Else we have a hard case with a negative exp.
                    //
                }
            } else if ((decExponent >= nDigits) && (nDigits + decExponent <= MAX_DECIMAL_DIGITS)) {
                //
                // 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 = kDigits; i < nDigits; i++) {
                    lValue = lValue * 10L + (long) ((int) digits[i] - (int) '0');
                }
                double dValue = (double) lValue;
                exp = decExponent - nDigits;
                dValue *= SMALL_10_POW[exp];
                fValue = (float) dValue;
                return (isNegative) ? -fValue : fValue;

            }
            //
            // 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.
            // Scaling uses doubles to avoid overflow/underflow.
            //
            double dValue = fValue;
            if (exp > 0) {
                if (decExponent > SINGLE_MAX_DECIMAL_EXPONENT + 1) {
                    //
                    // Lets face it. This is going to be
                    // Infinity. Cut to the chase.
                    //
                    return (isNegative) ? Float.NEGATIVE_INFINITY : Float.POSITIVE_INFINITY;
                }
                if ((exp & 15) != 0) {
                    dValue *= SMALL_10_POW[exp & 15];
                }
                if ((exp >>= 4) != 0) {
                    int j;
                    for (j = 0; exp > 0; j++, exp >>= 1) {
                        if ((exp & 1) != 0) {
                            dValue *= BIG_10_POW[j];
                        }
                    }
                }
            } else if (exp < 0) {
                exp = -exp;
                if (decExponent < SINGLE_MIN_DECIMAL_EXPONENT - 1) {
                    //
                    // Lets face it. This is going to be
                    // zero. Cut to the chase.
                    //
                    return (isNegative) ? -0.0f : 0.0f;
                }
                if ((exp & 15) != 0) {
                    dValue /= SMALL_10_POW[exp & 15];
                }
                if ((exp >>= 4) != 0) {
                    int j;
                    for (j = 0; exp > 0; j++, exp >>= 1) {
                        if ((exp & 1) != 0) {
                            dValue *= TINY_10_POW[j];
                        }
                    }
                }
            }
            fValue = Math.max(Float.MIN_VALUE, Math.min(Float.MAX_VALUE, (float) dValue));

            //
            // fValue is now approximately the result.
            // The hard part is adjusting it, by comparison
            // with FDBigInteger arithmetic.
            // Formulate the EXACT big-number result as
            // bigD0 * 10^exp
            //
            if (nDigits > SINGLE_MAX_NDIGITS) {
                nDigits = SINGLE_MAX_NDIGITS + 1;
                digits[SINGLE_MAX_NDIGITS] = '1';
            }
            FDBigInteger bigD0 = new FDBigInteger(iValue, digits, kDigits, nDigits);
            exp = decExponent - nDigits;

            int ieeeBits = Float.floatToRawIntBits(fValue); // IEEE-754 bits of float candidate
            final int B5 = Math.max(0, -exp); // powers of 5 in bigB, value is not modified inside correctionLoop
            final int D5 = Math.max(0, exp); // powers of 5 in bigD, value is not modified inside correctionLoop
            bigD0 = bigD0.multByPow52(D5, 0);
            bigD0.makeImmutable();   // prevent bigD0 modification inside correctionLoop
            FDBigInteger bigD = null;
            int prevD2 = 0;

            correctionLoop:
            while (true) {
                // here ieeeBits can't be NaN, Infinity or zero
                int binexp = ieeeBits >>> SINGLE_EXP_SHIFT;
                int bigBbits = ieeeBits & FloatConsts.SIGNIF_BIT_MASK;
                if (binexp > 0) {
                    bigBbits |= SINGLE_FRACT_HOB;
                } else { // Normalize denormalized numbers.
                    assert bigBbits != 0 : bigBbits; // floatToBigInt(0.0)
                    int leadingZeros = Integer.numberOfLeadingZeros(bigBbits);
                    int shift = leadingZeros - (31 - SINGLE_EXP_SHIFT);
                    bigBbits <<= shift;
                    binexp = 1 - shift;
                }
                binexp -= FloatConsts.EXP_BIAS;
                int lowOrderZeros = Integer.numberOfTrailingZeros(bigBbits);
                bigBbits >>>= lowOrderZeros;
                final int bigIntExp = binexp - SINGLE_EXP_SHIFT + lowOrderZeros;
                final int bigIntNBits = SINGLE_EXP_SHIFT + 1 - lowOrderZeros;

                //
                // Scale bigD, bigB appropriately for
                // big-integer operations.
                // Naively, we multiply 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 B2 = B5; // powers of 2 in bigB
                int D2 = D5; // powers of 2 in bigD
                int Ulp2;   // powers of 2 in halfUlp.
                if (bigIntExp >= 0) {
                    B2 += bigIntExp;
                } else {
                    D2 -= bigIntExp;
                }
                Ulp2 = B2;
                // shift bigB and bigD left by a number s. t.
                // halfUlp is still an integer.
                int hulpbias;
                if (binexp <= -FloatConsts.EXP_BIAS) {
                    // This is going to be a denormalized number
                    // (if not actually zero).
                    // half an ULP is at 2^-(FloatConsts.EXP_BIAS+SINGLE_EXP_SHIFT+1)
                    hulpbias = binexp + lowOrderZeros + FloatConsts.EXP_BIAS;
                } else {
                    hulpbias = 1 + lowOrderZeros;
                }
                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.min(B2, Math.min(D2, Ulp2));
                B2 -= common2;
                D2 -= common2;
                Ulp2 -= common2;
                // do multiplications by powers of 5 and 2
                FDBigInteger bigB = FDBigInteger.valueOfMulPow52(bigBbits, B5, B2);
                if (bigD == null || prevD2 != D2) {
                    bigD = bigD0.leftShift(D2);
                    prevD2 = D2;
                }
                //
                // 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.
                //
                FDBigInteger diff;
                int cmpResult;
                boolean overvalue;
                if ((cmpResult = bigB.cmp(bigD)) > 0) {
                    overvalue = true; // our candidate is too big.
                    diff = bigB.leftInplaceSub(bigD); // bigB is not user further - reuse
                    if ((bigIntNBits == 1) && (bigIntExp > -FloatConsts.EXP_BIAS + 1)) {
                        // candidate is a normalized exact power of 2 and
                        // is too big (larger than Float.MIN_NORMAL). 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 = diff.leftShift(1);
                        }
                    }
                } else if (cmpResult < 0) {
                    overvalue = false; // our candidate is too small.
                    diff = bigD.rightInplaceSub(bigB); // bigB is not user further - reuse
                } else {
                    // the candidate is exactly right!
                    // this happens with surprising frequency
                    break correctionLoop;
                }
                cmpResult = diff.cmpPow52(B5, Ulp2);
                if ((cmpResult) < 0) {
                    // difference is small.
                    // this is close enough
                    break correctionLoop;
                } else if (cmpResult == 0) {
                    // difference is exactly half an ULP
                    // round to some other value maybe, then finish
                    if ((ieeeBits & 1) != 0) { // half ties to even
                        ieeeBits += overvalue ? -1 : 1; // nextDown or nextUp
                    }
                    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.
                    ieeeBits += overvalue ? -1 : 1; // nextDown or nextUp
                    if (ieeeBits == 0 || ieeeBits == FloatConsts.EXP_BIT_MASK) { // 0.0 or Float.POSITIVE_INFINITY
                        break correctionLoop; // oops. Fell off end of range.
                    }
                    continue; // try again.
                }

            }
            if (isNegative) {
                ieeeBits |= FloatConsts.SIGN_BIT_MASK;
            }
            return Float.intBitsToFloat(ieeeBits);
        }


        /**
         * All the positive powers of 10 that can be
         * represented exactly in double/float.
         */
        private static final double[] SMALL_10_POW = {
            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[] SINGLE_SMALL_10_POW = {
            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[] BIG_10_POW = {
            1e16, 1e32, 1e64, 1e128, 1e256 };
        private static final double[] TINY_10_POW = {
            1e-16, 1e-32, 1e-64, 1e-128, 1e-256 };

        private static final int MAX_SMALL_TEN = SMALL_10_POW.length-1;
        private static final int SINGLE_MAX_SMALL_TEN = SINGLE_SMALL_10_POW.length-1;

    }

    /**
     * Returns a <code>BinaryToASCIIConverter</code> for a <code>double</code>.
     * The returned object is a <code>ThreadLocal</code> variable of this class.
     *
     * @param d The double precision value to convert.
     * @return The converter.
     */
    public static BinaryToASCIIConverter getBinaryToASCIIConverter(double d) {
        return getBinaryToASCIIConverter(d, true);
    }

    /**
     * Returns a <code>BinaryToASCIIConverter</code> for a <code>double</code>.
     * The returned object is a <code>ThreadLocal</code> variable of this class.
     *
     * @param d The double precision value to convert.
     * @param isCompatibleFormat
     * @return The converter.
     */
    static BinaryToASCIIConverter getBinaryToASCIIConverter(double d, boolean isCompatibleFormat) {
        long dBits = Double.doubleToRawLongBits(d);
        boolean isNegative = (dBits&DoubleConsts.SIGN_BIT_MASK) != 0; // discover sign
        long fractBits = dBits & DoubleConsts.SIGNIF_BIT_MASK;
        int  binExp = (int)( (dBits&DoubleConsts.EXP_BIT_MASK) >> EXP_SHIFT );
        // Discover obvious special cases of NaN and Infinity.
        if ( binExp == (int)(DoubleConsts.EXP_BIT_MASK>>EXP_SHIFT) ) {
            if ( fractBits == 0L ){
                return isNegative ? B2AC_NEGATIVE_INFINITY : B2AC_POSITIVE_INFINITY;
            } else {
                return B2AC_NOT_A_NUMBER;
            }
        }
        // Finish unpacking
        // Normalize denormalized numbers.
        // Insert assumed high-order bit for normalized numbers.
        // Subtract exponent bias.
        int  nSignificantBits;
        if ( binExp == 0 ){
            if ( fractBits == 0L ){
                // not a denorm, just a 0!
                return isNegative ? B2AC_NEGATIVE_ZERO : B2AC_POSITIVE_ZERO;
            }
            int leadingZeros = Long.numberOfLeadingZeros(fractBits);
            int shift = leadingZeros-(63-EXP_SHIFT);
            fractBits <<= shift;
            binExp = 1 - shift;
            nSignificantBits =  64-leadingZeros; // recall binExp is  - shift count.
        } else {
            fractBits |= FRACT_HOB;
            nSignificantBits = EXP_SHIFT+1;
        }
        binExp -= DoubleConsts.EXP_BIAS;
        BinaryToASCIIBuffer buf = getBinaryToASCIIBuffer();
        buf.setSign(isNegative);
        // call the routine that actually does all the hard work.
        buf.dtoa(binExp, fractBits, nSignificantBits, isCompatibleFormat);
        return buf;
    }

    private static BinaryToASCIIConverter getBinaryToASCIIConverter(float f) {
        int fBits = Float.floatToRawIntBits( f );
        boolean isNegative = (fBits&FloatConsts.SIGN_BIT_MASK) != 0;
        int fractBits = fBits&FloatConsts.SIGNIF_BIT_MASK;
        int binExp = (fBits&FloatConsts.EXP_BIT_MASK) >> SINGLE_EXP_SHIFT;
        // Discover obvious special cases of NaN and Infinity.
        if ( binExp == (FloatConsts.EXP_BIT_MASK>>SINGLE_EXP_SHIFT) ) {
            if ( fractBits == 0L ){
                return isNegative ? B2AC_NEGATIVE_INFINITY : B2AC_POSITIVE_INFINITY;
            } else {
                return B2AC_NOT_A_NUMBER;
            }
        }
        // Finish unpacking
        // Normalize denormalized numbers.
        // Insert assumed high-order bit for normalized numbers.
        // Subtract exponent bias.
        int  nSignificantBits;
        if ( binExp == 0 ){
            if ( fractBits == 0 ){
                // not a denorm, just a 0!
                return isNegative ? B2AC_NEGATIVE_ZERO : B2AC_POSITIVE_ZERO;
            }
            int leadingZeros = Integer.numberOfLeadingZeros(fractBits);
            int shift = leadingZeros-(31-SINGLE_EXP_SHIFT);
            fractBits <<= shift;
            binExp = 1 - shift;
            nSignificantBits =  32 - leadingZeros; // recall binExp is  - shift count.
        } else {
            fractBits |= SINGLE_FRACT_HOB;
            nSignificantBits = SINGLE_EXP_SHIFT+1;
        }
        binExp -= FloatConsts.EXP_BIAS;
        BinaryToASCIIBuffer buf = getBinaryToASCIIBuffer();
        buf.setSign(isNegative);
        // call the routine that actually does all the hard work.
        buf.dtoa(binExp, ((long)fractBits)<<(EXP_SHIFT-SINGLE_EXP_SHIFT), nSignificantBits, true);
        return buf;
    }

    @SuppressWarnings("fallthrough")
    static ASCIIToBinaryConverter readJavaFormatString( String in ) throws NumberFormatException {
        boolean isNegative = false;
        boolean signSeen   = false;
        int     decExp;
        char    c;

    parseNumber:
        try{
            in = in.trim(); // don't fool around with white space.
                            // throws NullPointerException if null
            int len = in.length();
            if ( len == 0 ) {
                throw new NumberFormatException("empty String");
            }
            int i = 0;
            switch (in.charAt(i)){
            case '-':
                isNegative = true;
                //FALLTHROUGH
            case '+':
                i++;
                signSeen = true;
            }
            c = in.charAt(i);
            if(c == 'N') { // Check for NaN
                if((len-i)==NAN_LENGTH && in.indexOf(NAN_REP,i)==i) {
                    return A2BC_NOT_A_NUMBER;
                }
                // something went wrong, throw exception
                break parseNumber;
            } else if(c == 'I') { // Check for Infinity strings
                if((len-i)==INFINITY_LENGTH && in.indexOf(INFINITY_REP,i)==i) {
                    return isNegative? A2BC_NEGATIVE_INFINITY : A2BC_POSITIVE_INFINITY;
                }
                // something went wrong, throw exception
                break parseNumber;
            } else if (c == '0')  { // check for hexadecimal floating-point number
                if (len > i+1 ) {
                    char ch = in.charAt(i+1);
                    if (ch == 'x' || ch == 'X' ) { // possible hex string
                        return parseHexString(in);
                    }
                }
            }  // look for and process decimal floating-point string

            char[] digits = new char[ len ];
            int    nDigits= 0;
            boolean decSeen = false;
            int decPt = 0;
            int nLeadZero = 0;
            int nTrailZero= 0;

        skipLeadingZerosLoop:
            while (i < len) {
                c = in.charAt(i);
                if (c == '0') {
                    nLeadZero++;
                } else if (c == '.') {
                    if (decSeen) {
                        // already saw one ., this is the 2nd.
                        throw new NumberFormatException("multiple points");
                    }
                    decPt = i;
                    if (signSeen) {
                        decPt -= 1;
                    }
                    decSeen = true;
                } else {
                    break skipLeadingZerosLoop;
                }
                i++;
            }
        digitLoop:
            while (i < len) {
                c = in.charAt(i);
                if (c >= '1' && c <= '9') {
                    digits[nDigits++] = c;
                    nTrailZero = 0;
                } else if (c == '0') {
                    digits[nDigits++] = c;
                    nTrailZero++;
                } else if (c == '.') {
                    if (decSeen) {
                        // already saw one ., this is the 2nd.
                        throw new NumberFormatException("multiple points");
                    }
                    decPt = i;
                    if (signSeen) {
                        decPt -= 1;
                    }
                    decSeen = true;
                } else {
                    break digitLoop;
                }
                i++;
            }
            nDigits -=nTrailZero;
            //
            // 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!
            //
            boolean isZero = (nDigits == 0);
            if ( isZero &&  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 < len) &&  (((c = in.charAt(i) )=='e') || (c == 'E') ) ){
                int expSign = 1;
                int expVal  = 0;
                int reallyBig = Integer.MAX_VALUE / 10;
                boolean expOverflow = false;
                switch( in.charAt(++i) ){
                case '-':
                    expSign = -1;
                    //FALLTHROUGH
                case '+':
                    i++;
                }
                int expAt = i;
            expLoop:
                while ( i < len  ){
                    if ( expVal >= reallyBig ){
                        // the next character will cause integer
                        // overflow.
                        expOverflow = true;
                    }
                    c = in.charAt(i++);
                    if(c>='0' && c<='9') {
                        expVal = expVal*10 + ( (int)c - (int)'0' );
                    } else {
                        i--;           // back up.
                        break expLoop; // stop parsing exponent.
                    }
                }
                int expLimit = BIG_DECIMAL_EXPONENT+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 < len &&
                ((i != len - 1) ||
                (in.charAt(i) != 'f' &&
                 in.charAt(i) != 'F' &&
                 in.charAt(i) != 'd' &&
                 in.charAt(i) != 'D'))) {
                break parseNumber; // go throw exception
            }
            if(isZero) {
                return isNegative ? A2BC_NEGATIVE_ZERO : A2BC_POSITIVE_ZERO;
            }
            return new ASCIIToBinaryBuffer(isNegative, decExp, digits, nDigits);
        } catch ( StringIndexOutOfBoundsException e ){ }
        throw new NumberFormatException("For input string: \"" + in + "\"");
    }

    private static class HexFloatPattern {
        /**
         * Grammar is compatible with hexadecimal floating-point constants
         * described in section 6.4.4.2 of the C99 specification.
         */
        private static final Pattern VALUE = Pattern.compile(
                   //1           234                   56                7                   8      9
                    "([-+])?0[xX](((\\p{XDigit}+)\\.?)|((\\p{XDigit}*)\\.(\\p{XDigit}+)))[pP]([-+])?(\\p{Digit}+)[fFdD]?"
                    );
    }

    /**
     * Converts string s to a suitable floating decimal; uses the
     * double constructor and sets the roundDir variable appropriately
     * in case the value is later converted to a float.
     *
     * @param s The <code>String</code> to parse.
     */
   static ASCIIToBinaryConverter parseHexString(String s) {
            // Verify string is a member of the hexadecimal floating-point
            // string language.
            Matcher m = HexFloatPattern.VALUE.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);
                boolean isNegative = ((group1 != null) && group1.equals("-"));

                //  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 isNegative ? A2BC_NEGATIVE_ZERO : A2BC_POSITIVE_ZERO;
                    }
                }

                //  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 isNegative ?
                              (positiveExponent ? A2BC_NEGATIVE_INFINITY : A2BC_NEGATIVE_ZERO)
                            : (positiveExponent ? A2BC_POSITIVE_INFINITY : A2BC_POSITIVE_ZERO);

                }

                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 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 conversion too large!");
                }
                // The preceding if-else could be replaced by a single
                // code block based on the high-order bit set in
                // leadingDigit.  Given leadingOnePosition,

                // significand |= leadingDigit << (SIGNIFICAND_WIDTH - leadingOnePosition);
                // nextShift = 52 - (3 + leadingOnePosition);
                // exponent += (leadingOnePosition-1);

                //
                // Now the exponent variable is equal to the normalized
                // binary exponent.  Code below will make representation
                // adjustments if the exponent is incremented after
                // rounding (includes overflows to infinity) or if the
                // result is subnormal.
                //

                // Copy digit into significand until the significand can't
                // hold another full hex digit or there are no more input
                // hex digits.
                int i = 0;
                for (i = 1;
                     i < signifLength && nextShift >= 0;
                     i++) {
                    long currentDigit = getHexDigit(significandString, i);
                    significand |= (currentDigit << nextShift);
                    nextShift -= 4;
                }

                // After the above loop, the bulk of the string is copied.
                // Now, we must copy any partial hex digits into the
                // significand AND compute the round bit and start computing
                // sticky bit.

                if (i < signifLength) { // at least one hex input digit exists
                    long currentDigit = getHexDigit(significandString, i);

                    // from nextShift, figure out how many bits need
                    // to be copied, if any
                    switch (nextShift) { // must be negative
                        case -1:
                            // three bits need to be copied in; can
                            // set round bit
                            significand |= ((currentDigit & 0xEL) >> 1);
                            round = (currentDigit & 0x1L) != 0L;
                            break;

                        case -2:
                            // two bits need to be copied in; can
                            // set round and start sticky
                            significand |= ((currentDigit & 0xCL) >> 2);
                            round = (currentDigit & 0x2L) != 0L;
                            sticky = (currentDigit & 0x1L) != 0;
                            break;

                        case -3:
                            // one bit needs to be copied in
                            significand |= ((currentDigit & 0x8L) >> 3);
                            // Now set round and start sticky, if possible
                            round = (currentDigit & 0x4L) != 0L;
                            sticky = (currentDigit & 0x3L) != 0;
                            break;

                        case -4:
                            // all bits copied into significand; set
                            // round and start sticky
                            round = ((currentDigit & 0x8L) != 0);  // is top bit set?
                            // nonzeros in three low order bits?
                            sticky = (currentDigit & 0x7L) != 0;
                            break;

                        default:
                            throw new AssertionError("Unexpected shift distance remainder.");
                            // break;
                    }

                    // Round is set; sticky might be set.

                    // For the sticky bit, it suffices to check the
                    // current digit and test for any nonzero digits in
                    // the remaining unprocessed input.
                    i++;
                    while (i < signifLength && !sticky) {
                        currentDigit = getHexDigit(significandString, i);
                        sticky = sticky || (currentDigit != 0);
                        i++;
                    }

                }
                // else all of string was seen, round and sticky are
                // correct as false.

                // Float calculations
                int floatBits = isNegative ? FloatConsts.SIGN_BIT_MASK : 0;
                if (exponent >= FloatConsts.MIN_EXPONENT) {
                    if (exponent > FloatConsts.MAX_EXPONENT) {
                        // Float.POSITIVE_INFINITY
                        floatBits |= FloatConsts.EXP_BIT_MASK;
                    } else {
                        int threshShift = DoubleConsts.SIGNIFICAND_WIDTH - FloatConsts.SIGNIFICAND_WIDTH - 1;
                        boolean floatSticky = (significand & ((1L << threshShift) - 1)) != 0 || round || sticky;
                        int iValue = (int) (significand >>> threshShift);
                        if ((iValue & 3) != 1 || floatSticky) {
                            iValue++;
                        }
                        floatBits |= (((((int) exponent) + (FloatConsts.EXP_BIAS - 1))) << SINGLE_EXP_SHIFT) + (iValue >> 1);
                    }
                } else {
                    if (exponent < FloatConsts.MIN_SUB_EXPONENT - 1) {
                        // 0
                    } else {
                        // exponent == -127 ==> threshShift = 53 - 2 + (-149) - (-127) = 53 - 24
                        int threshShift = (int) ((DoubleConsts.SIGNIFICAND_WIDTH - 2 + FloatConsts.MIN_SUB_EXPONENT) - exponent);
                        assert threshShift >= DoubleConsts.SIGNIFICAND_WIDTH - FloatConsts.SIGNIFICAND_WIDTH;
                        assert threshShift < DoubleConsts.SIGNIFICAND_WIDTH;
                        boolean floatSticky = (significand & ((1L << threshShift) - 1)) != 0 || round || sticky;
                        int iValue = (int) (significand >>> threshShift);
                        if ((iValue & 3) != 1 || floatSticky) {
                            iValue++;
                        }
                        floatBits |= iValue >> 1;
                    }
                }
                float fValue = Float.intBitsToFloat(floatBits);

                // Check for overflow and update exponent accordingly.
                if (exponent > DoubleConsts.MAX_EXPONENT) {         // Infinite result
                    // overflow to properly signed infinity
                    return isNegative ? A2BC_NEGATIVE_INFINITY : A2BC_POSITIVE_INFINITY;
                } else {  // Finite return value
                    if (exponent <= DoubleConsts.MAX_EXPONENT && // (Usually) normal result
                            exponent >= DoubleConsts.MIN_EXPONENT) {

                        // The result returned in this block cannot be a
                        // zero or subnormal; however after the
                        // significand is adjusted from rounding, we could
                        // still overflow in infinity.

                        // AND exponent bits into significand; if the
                        // significand is incremented and overflows from
                        // rounding, this combination will update the
                        // exponent correctly, even in the case of
                        // Double.MAX_VALUE overflowing to infinity.

                        significand = ((( exponent +
                                (long) DoubleConsts.EXP_BIAS) <<
                                (DoubleConsts.SIGNIFICAND_WIDTH - 1))
                                & DoubleConsts.EXP_BIT_MASK) |
                                (DoubleConsts.SIGNIF_BIT_MASK & significand);

                    } else {  // Subnormal or zero
                        // (exponent < DoubleConsts.MIN_EXPONENT)

                        if (exponent < (DoubleConsts.MIN_SUB_EXPONENT - 1)) {
                            // No way to round back to nonzero value
                            // regardless of significand if the exponent is
                            // less than -1075.
                            return isNegative ? A2BC_NEGATIVE_ZERO : A2BC_POSITIVE_ZERO;
                        } else { //  -1075 <= exponent <= MIN_EXPONENT -1 = -1023
                            //
                            // Find bit position to round to; recompute
                            // round and sticky bits, and shift
                            // significand right appropriately.
                            //

                            sticky = sticky || round;
                            round = false;

                            // Number of bits of significand to preserve is
                            // exponent - abs_min_exp +1
                            // check:
                            // -1075 +1074 + 1 = 0
                            // -1023 +1074 + 1 = 52

                            int bitsDiscarded = 53 -
                                    ((int) exponent - DoubleConsts.MIN_SUB_EXPONENT + 1);
                            assert bitsDiscarded >= 1 && bitsDiscarded <= 53;

                            // What to do here:
                            // First, isolate the new round bit
                            round = (significand & (1L << (bitsDiscarded - 1))) != 0L;
                            if (bitsDiscarded > 1) {
                                // create mask to update sticky bits; low
                                // order bitsDiscarded bits should be 1
                                long mask = ~((~0L) << (bitsDiscarded - 1));
                                sticky = sticky || ((significand & mask) != 0L);
                            }

                            // Now, discard the bits
                            significand = significand >> bitsDiscarded;

                            significand = ((((long) (DoubleConsts.MIN_EXPONENT - 1) + // subnorm exp.
                                    (long) DoubleConsts.EXP_BIAS) <<
                                    (DoubleConsts.SIGNIFICAND_WIDTH - 1))
                                    & DoubleConsts.EXP_BIT_MASK) |
                                    (DoubleConsts.SIGNIF_BIT_MASK & significand);
                        }
                    }

                    // The significand variable now contains the currently
                    // appropriate exponent bits too.

                    //
                    // Determine if significand should be incremented;
                    // making this determination depends on the least
                    // significant bit and the round and sticky bits.
                    //
                    // Round to nearest even rounding table, adapted from
                    // table 4.7 in "Computer Arithmetic" by IsraelKoren.
                    // The digit to the left of the "decimal" point is the
                    // least significant bit, the digits to the right of
                    // the point are the round and sticky bits
                    //
                    // Number       Round(x)
                    // x0.00        x0.
                    // x0.01        x0.
                    // x0.10        x0.
                    // x0.11        x1. = x0. +1
                    // x1.00        x1.
                    // x1.01        x1.
                    // x1.10        x1. + 1
                    // x1.11        x1. + 1
                    //
                    boolean leastZero = ((significand & 1L) == 0L);
                    if ((leastZero && round && sticky) ||
                            ((!leastZero) && round)) {
                        significand++;
                    }

                    double value = isNegative ?
                            Double.longBitsToDouble(significand | DoubleConsts.SIGN_BIT_MASK) :
                            Double.longBitsToDouble(significand );

                    return new PreparedASCIIToBinaryBuffer(value, fValue);
                }
            }
    }

    /**
     * Returns <code>s</code> with any leading zeros removed.
     */
    static String stripLeadingZeros(String s) {
//        return  s.replaceFirst("^0+", "");
        if(!s.isEmpty() && s.charAt(0)=='0') {
            for(int i=1; i<s.length(); i++) {
                if(s.charAt(i)!='0') {
                    return s.substring(i);
                }
            }
            return "";
        }
        return s;
    }

    /**
     * Extracts a hexadecimal digit from position <code>position</code>
     * of string <code>s</code>.
     */
    static int getHexDigit(String s, int position) {
        int value = Character.digit(s.charAt(position), 16);
        if (value <= -1 || value >= 16) {
            throw new AssertionError("Unexpected failure of digit conversion of " +
                                     s.charAt(position));
        }
        return value;
    }
}
