151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/*
251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it
651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as
751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation.  Oracle designates this
851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided
951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code.
1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT
1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that
1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code).
1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version
1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation,
1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any
2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions.
2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */
2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage sun.misc;
2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.misc.FpUtils;
2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.misc.DoubleConsts;
3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.misc.FloatConsts;
3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.regex.*;
3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipublic class FormattedFloatingDecimal{
3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    boolean     isExceptional;
3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    boolean     isNegative;
3651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    int         decExponent;  // value set at construction, then immutable
3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    int         decExponentRounded;
3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    char        digits[];
3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    int         nDigits;
4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    int         bigIntExp;
4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    int         bigIntNBits;
4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    boolean     mustSetRoundDir = false;
4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    boolean     fromHex = false;
4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    int         roundDir = 0; // set by doubleValue
4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    int         precision;    // number of digits to the right of decimal
4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public enum Form { SCIENTIFIC, COMPATIBLE, DECIMAL_FLOAT, GENERAL };
4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private Form form;
5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private     FormattedFloatingDecimal( boolean negSign, int decExponent, char []digits, int n, boolean e, int precision, Form form )
5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    {
5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        isNegative = negSign;
5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        isExceptional = e;
5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.decExponent = decExponent;
5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.digits = digits;
5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.nDigits = n;
5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.precision = precision;
5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.form = form;
6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /*
6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Constants of the implementation
6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Most are IEEE-754 related.
6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * (There are more really boring constants at the end.)
6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final long   signMask = 0x8000000000000000L;
6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final long   expMask  = 0x7ff0000000000000L;
6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final long   fractMask= ~(signMask|expMask);
7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final int    expShift = 52;
7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final int    expBias  = 1023;
7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final long   fractHOB = ( 1L<<expShift ); // assumed High-Order bit
7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final long   expOne   = ((long)expBias)<<expShift; // exponent of 1.0
7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final int    maxSmallBinExp = 62;
7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final int    minSmallBinExp = -( 63 / 3 );
7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final int    maxDecimalDigits = 15;
7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final int    maxDecimalExponent = 308;
7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final int    minDecimalExponent = -324;
7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final int    bigDecimalExponent = 324; // i.e. abs(minDecimalExponent)
8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final long   highbyte = 0xff00000000000000L;
8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final long   highbit  = 0x8000000000000000L;
8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final long   lowbytes = ~highbyte;
8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final int    singleSignMask =    0x80000000;
8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final int    singleExpMask  =    0x7f800000;
8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final int    singleFractMask =   ~(singleSignMask|singleExpMask);
8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final int    singleExpShift  =   23;
8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final int    singleFractHOB  =   1<<singleExpShift;
9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final int    singleExpBias   =   127;
9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final int    singleMaxDecimalDigits = 7;
9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final int    singleMaxDecimalExponent = 38;
9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final int    singleMinDecimalExponent = -45;
9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final int    intDecimalDigits = 9;
9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /*
9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * count number of bits from high-order 1 bit to low-order 1 bit,
10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * inclusive.
10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static int
10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    countBits( long v ){
10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        //
10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // the strategy is to shift until we get a non-zero sign bit
10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // then shift until we have no bits left, counting the difference.
10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // we do byte shifting as a hack. Hope it helps.
10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        //
10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( v == 0L ) return 0;
11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        while ( ( v & highbyte ) == 0L ){
11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            v <<= 8;
11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        while ( v > 0L ) { // i.e. while ((v&highbit) == 0L )
11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            v <<= 1;
11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int n = 0;
11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        while (( v & lowbytes ) != 0L ){
12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            v <<= 8;
12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            n += 8;
12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        while ( v != 0L ){
12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            v <<= 1;
12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            n += 1;
12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return n;
12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /*
13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Keep big powers of 5 handy for future reference.
13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static FDBigInt b5p[];
13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static synchronized FDBigInt
13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    big5pow( int p ){
13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        assert p >= 0 : p; // negative power of 5
13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( b5p == null ){
13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            b5p = new FDBigInt[ p+1 ];
14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }else if (b5p.length <= p ){
14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            FDBigInt t[] = new FDBigInt[ p+1 ];
14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            System.arraycopy( b5p, 0, t, 0, b5p.length );
14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            b5p = t;
14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( b5p[p] != null )
14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return b5p[p];
14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        else if ( p < small5pow.length )
14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return b5p[p] = new FDBigInt( small5pow[p] );
14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        else if ( p < long5pow.length )
15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return b5p[p] = new FDBigInt( long5pow[p] );
15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        else {
15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // construct the value.
15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // recursively.
15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            int q, r;
15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // in order to compute 5^p,
15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // compute its square root, 5^(p/2) and square.
15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // or, let q = p / 2, r = p -q, then
15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // 5^p = 5^(q+r) = 5^q * 5^r
15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            q = p >> 1;
16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            r = p - q;
16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            FDBigInt bigq =  b5p[q];
16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ( bigq == null )
16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                bigq = big5pow ( q );
16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ( r < small5pow.length ){
16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return (b5p[p] = bigq.mult( small5pow[r] ) );
16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }else{
16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                FDBigInt bigr = b5p[ r ];
16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if ( bigr == null )
16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    bigr = big5pow( r );
17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return (b5p[p] = bigq.mult( bigr ) );
17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
17351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
17451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
17551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    //
17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // a common operation
17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    //
17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static FDBigInt
17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    multPow52( FDBigInt v, int p5, int p2 ){
18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( p5 != 0 ){
18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ( p5 < small5pow.length ){
18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                v = v.mult( small5pow[p5] );
18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else {
18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                v = v.mult( big5pow( p5 ) );
18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( p2 != 0 ){
18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            v.lshiftMe( p2 );
18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return v;
19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    //
19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // another common operation
19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    //
19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static FDBigInt
19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    constructPow52( int p5, int p2 ){
19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        FDBigInt v = new FDBigInt( big5pow( p5 ) );
19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( p2 != 0 ){
20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            v.lshiftMe( p2 );
20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return v;
20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /*
20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Make a floating double into a FDBigInt.
20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * This could also be structured as a FDBigInt
20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * constructor, but we'd have to build a lot of knowledge
20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * about floating-point representation into it, and we don't want to.
21051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * AS A SIDE EFFECT, THIS METHOD WILL SET THE INSTANCE VARIABLES
21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * bigIntExp and bigIntNBits
21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private FDBigInt
21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    doubleToBigInt( double dval ){
21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        long lbits = Double.doubleToLongBits( dval ) & ~signMask;
21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int binexp = (int)(lbits >>> expShift);
21951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        lbits &= fractMask;
22051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( binexp > 0 ){
22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            lbits |= fractHOB;
22251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
22351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            assert lbits != 0L : lbits; // doubleToBigInt(0.0)
22451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            binexp +=1;
22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            while ( (lbits & fractHOB ) == 0L){
22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                lbits <<= 1;
22751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                binexp -= 1;
22851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
22951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
23051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        binexp -= expBias;
23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int nbits = countBits( lbits );
23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        /*
23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * We now know where the high-order 1 bit is,
23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * and we know how many there are.
23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         */
23651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int lowOrderZeros = expShift+1-nbits;
23751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        lbits >>>= lowOrderZeros;
23851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
23951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        bigIntExp = binexp+1-nbits;
24051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        bigIntNBits = nbits;
24151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return new FDBigInt( lbits );
24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /*
24551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Compute a number that is the ULP of the given value,
24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * for purposes of addition/subtraction. Generally easy.
24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * More difficult if subtracting and the argument
24851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * is a normalized a power of 2, as the ULP changes at these points.
24951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static double ulp( double dval, boolean subtracting ){
25151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        long lbits = Double.doubleToLongBits( dval ) & ~signMask;
25251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int binexp = (int)(lbits >>> expShift);
25351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        double ulpval;
25451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( subtracting && ( binexp >= expShift ) && ((lbits&fractMask) == 0L) ){
25551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // for subtraction from normalized, powers of 2,
25651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // use next-smaller exponent
25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            binexp -= 1;
25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
25951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( binexp > expShift ){
26051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            ulpval = Double.longBitsToDouble( ((long)(binexp-expShift))<<expShift );
26151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else if ( binexp == 0 ){
26251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            ulpval = Double.MIN_VALUE;
26351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
26451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            ulpval = Double.longBitsToDouble( 1L<<(binexp-1) );
26551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
26651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( subtracting ) ulpval = - ulpval;
26751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return ulpval;
26951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
27051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
27151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /*
27251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Round a double to a float.
27351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * In addition to the fraction bits of the double,
27451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * look at the class instance variable roundDir,
27551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * which should help us avoid double-rounding error.
27651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * roundDir was set in hardValueOf if the estimate was
27751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * close enough, but not exact. It tells us which direction
27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * of rounding is preferred.
27951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
28051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    float
28151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    stickyRound( double dval ){
28251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        long lbits = Double.doubleToLongBits( dval );
28351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        long binexp = lbits & expMask;
28451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( binexp == 0L || binexp == expMask ){
28551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // what we have here is special.
28651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // don't worry, the right thing will happen.
28751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return (float) dval;
28851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
28951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        lbits += (long)roundDir; // hack-o-matic.
29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return (float)Double.longBitsToDouble( lbits );
29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /*
29551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * This is the easy subcase --
29651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * all the significant bits, after scaling, are held in lvalue.
29751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * negSign and decExponent tell us what processing and scaling
29851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * has already been done. Exceptional cases have already been
29951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * stripped out.
30051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * In particular:
30151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * lvalue is a finite number (not Inf, nor NaN)
30251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * lvalue > 0L (not zero, nor negative).
30351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
30451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * The only reason that we develop the digits here, rather than
30551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * calling on Long.toString() is that we can do it a little faster,
30651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * and besides want to treat trailing 0s specially. If Long.toString
30751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * changes, we should re-evaluate this strategy!
30851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
30951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private void
31051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    developLongDigits( int decExponent, long lvalue, long insignificant ){
31151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        char digits[];
31251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int  ndigits;
31351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int  digitno;
31451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int  c;
31551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        //
31651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Discard non-significant low-order bits, while rounding,
31751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // up to insignificant value.
31851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int i;
31951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        for ( i = 0; insignificant >= 10L; i++ )
32051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            insignificant /= 10L;
32151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( i != 0 ){
32251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            long pow10 = long5pow[i] << i; // 10^i == 5^i * 2^i;
32351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            long residue = lvalue % pow10;
32451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            lvalue /= pow10;
32551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            decExponent += i;
32651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ( residue >= (pow10>>1) ){
32751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // round up based on the low-order bits we're discarding
32851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                lvalue++;
32951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
33051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
33151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( lvalue <= Integer.MAX_VALUE ){
33251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            assert lvalue > 0L : lvalue; // lvalue <= 0
33351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // even easier subcase!
33451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // can do int arithmetic rather than long!
33551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            int  ivalue = (int)lvalue;
33651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            ndigits = 10;
33751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            digits = (char[])(perThreadBuffer.get());
33851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            digitno = ndigits-1;
33951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            c = ivalue%10;
34051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            ivalue /= 10;
34151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            while ( c == 0 ){
34251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                decExponent++;
34351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                c = ivalue%10;
34451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                ivalue /= 10;
34551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
34651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            while ( ivalue != 0){
34751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                digits[digitno--] = (char)(c+'0');
34851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                decExponent++;
34951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                c = ivalue%10;
35051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                ivalue /= 10;
35151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
35251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            digits[digitno] = (char)(c+'0');
35351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
35451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // same algorithm as above (same bugs, too )
35551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // but using long arithmetic.
35651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            ndigits = 20;
35751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            digits = (char[])(perThreadBuffer.get());
35851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            digitno = ndigits-1;
35951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            c = (int)(lvalue%10L);
36051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            lvalue /= 10L;
36151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            while ( c == 0 ){
36251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                decExponent++;
36351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                c = (int)(lvalue%10L);
36451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                lvalue /= 10L;
36551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
36651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            while ( lvalue != 0L ){
36751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                digits[digitno--] = (char)(c+'0');
36851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                decExponent++;
36951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                c = (int)(lvalue%10L);
37051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                lvalue /= 10;
37151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
37251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            digits[digitno] = (char)(c+'0');
37351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
37451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        char result [];
37551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        ndigits -= digitno;
37651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        result = new char[ ndigits ];
37751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        System.arraycopy( digits, digitno, result, 0, ndigits );
37851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.digits = result;
37951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.decExponent = decExponent+1;
38051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.nDigits = ndigits;
38151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
38251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
38351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    //
38451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // add one to the least significant digit.
38551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // in the unlikely event there is a carry out,
38651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // deal with it.
38751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // assert that this will only happen where there
38851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // is only one digit, e.g. (float)1e-44 seems to do it.
38951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    //
39051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private void
39151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    roundup(){
39251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int i;
39351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int q = digits[ i = (nDigits-1)];
39451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( q == '9' ){
39551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            while ( q == '9' && i > 0 ){
39651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                digits[i] = '0';
39751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                q = digits[--i];
39851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
39951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ( q == '9' ){
40051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // carryout! High-order 1, rest 0s, larger exp.
40151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                decExponent += 1;
40251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                digits[0] = '1';
40351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return;
40451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
40551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // else fall through.
40651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
40751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        digits[i] = (char)(q+1);
40851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
40951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
41051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // Given the desired number of digits predict the result's exponent.
41151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private int checkExponent(int length) {
41251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (length >= nDigits || length < 0)
41351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return decExponent;
41451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
41551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        for (int i = 0; i < length; i++)
41651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (digits[i] != '9')
41751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // a '9' anywhere in digits will absorb the round
41851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return decExponent;
41951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return decExponent + (digits[length] >= '5' ? 1 : 0);
42051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
42151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
42251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // Unlike roundup(), this method does not modify digits.  It also
42351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // rounds at a particular precision.
42451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private char [] applyPrecision(int length) {
42551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        char [] result = new char[nDigits];
42651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        for (int i = 0; i < result.length; i++) result[i] = '0';
42751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
42851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (length >= nDigits || length < 0) {
42951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // no rounding necessary
43051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            System.arraycopy(digits, 0, result, 0, nDigits);
43151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return result;
43251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
43351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (length == 0) {
43451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // only one digit (0 or 1) is returned because the precision
43551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // excludes all significant digits
43651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (digits[0] >= '5') {
43751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                result[0] = '1';
43851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
43951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return result;
44051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
44151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
44251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int i = length;
44351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int q = digits[i];
44451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (q >= '5' && i > 0) {
44551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            q = digits[--i];
44651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ( q == '9' ) {
44751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                while ( q == '9' && i > 0 ){
44851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    q = digits[--i];
44951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
45051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if ( q == '9' ){
45151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // carryout! High-order 1, rest 0s, larger exp.
45251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    result[0] = '1';
45351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    return result;
45451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
45551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
45651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            result[i] = (char)(q + 1);
45751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
45851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        while (--i >= 0) {
45951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            result[i] = digits[i];
46051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
46151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return result;
46251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
46351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
46451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /*
46551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * FIRST IMPORTANT CONSTRUCTOR: DOUBLE
46651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
46751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public FormattedFloatingDecimal( double d )
46851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    {
46951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this(d, Integer.MAX_VALUE, Form.COMPATIBLE);
47051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
47151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
47251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public FormattedFloatingDecimal( double d, int precision, Form form )
47351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    {
47451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        long    dBits = Double.doubleToLongBits( d );
47551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        long    fractBits;
47651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int     binExp;
47751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int     nSignificantBits;
47851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
47951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.precision = precision;
48051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.form      = form;
48151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
48251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // discover and delete sign
48351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( (dBits&signMask) != 0 ){
48451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            isNegative = true;
48551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            dBits ^= signMask;
48651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
48751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            isNegative = false;
48851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
48951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Begin to unpack
49051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Discover obvious special cases of NaN and Infinity.
49151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        binExp = (int)( (dBits&expMask) >> expShift );
49251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        fractBits = dBits&fractMask;
49351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( binExp == (int)(expMask>>expShift) ) {
49451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            isExceptional = true;
49551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ( fractBits == 0L ){
49651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                digits =  infinity;
49751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else {
49851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                digits = notANumber;
49951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                isNegative = false; // NaN has no sign!
50051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
50151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            nDigits = digits.length;
50251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return;
50351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
50451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        isExceptional = false;
50551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Finish unpacking
50651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Normalize denormalized numbers.
50751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Insert assumed high-order bit for normalized numbers.
50851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Subtract exponent bias.
50951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( binExp == 0 ){
51051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ( fractBits == 0L ){
51151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // not a denorm, just a 0!
51251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                decExponent = 0;
51351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                digits = zero;
51451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                nDigits = 1;
51551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return;
51651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
51751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            while ( (fractBits&fractHOB) == 0L ){
51851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                fractBits <<= 1;
51951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                binExp -= 1;
52051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
52151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            nSignificantBits = expShift + binExp +1; // recall binExp is  - shift count.
52251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            binExp += 1;
52351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
52451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            fractBits |= fractHOB;
52551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            nSignificantBits = expShift+1;
52651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
52751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        binExp -= expBias;
52851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // call the routine that actually does all the hard work.
52951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        dtoa( binExp, fractBits, nSignificantBits );
53051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
53151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
53251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /*
53351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * SECOND IMPORTANT CONSTRUCTOR: SINGLE
53451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
53551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public FormattedFloatingDecimal( float f )
53651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    {
53751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this(f, Integer.MAX_VALUE, Form.COMPATIBLE);
53851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
53951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public FormattedFloatingDecimal( float f, int precision, Form form )
54051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    {
54151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int     fBits = Float.floatToIntBits( f );
54251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int     fractBits;
54351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int     binExp;
54451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int     nSignificantBits;
54551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
54651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.precision = precision;
54751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.form      = form;
54851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
54951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // discover and delete sign
55051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( (fBits&singleSignMask) != 0 ){
55151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            isNegative = true;
55251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            fBits ^= singleSignMask;
55351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
55451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            isNegative = false;
55551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
55651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Begin to unpack
55751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Discover obvious special cases of NaN and Infinity.
55851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        binExp = (int)( (fBits&singleExpMask) >> singleExpShift );
55951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        fractBits = fBits&singleFractMask;
56051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( binExp == (int)(singleExpMask>>singleExpShift) ) {
56151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            isExceptional = true;
56251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ( fractBits == 0L ){
56351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                digits =  infinity;
56451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else {
56551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                digits = notANumber;
56651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                isNegative = false; // NaN has no sign!
56751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
56851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            nDigits = digits.length;
56951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return;
57051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
57151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        isExceptional = false;
57251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Finish unpacking
57351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Normalize denormalized numbers.
57451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Insert assumed high-order bit for normalized numbers.
57551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Subtract exponent bias.
57651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( binExp == 0 ){
57751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ( fractBits == 0 ){
57851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // not a denorm, just a 0!
57951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                decExponent = 0;
58051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                digits = zero;
58151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                nDigits = 1;
58251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return;
58351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
58451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            while ( (fractBits&singleFractHOB) == 0 ){
58551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                fractBits <<= 1;
58651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                binExp -= 1;
58751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
58851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            nSignificantBits = singleExpShift + binExp +1; // recall binExp is  - shift count.
58951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            binExp += 1;
59051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
59151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            fractBits |= singleFractHOB;
59251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            nSignificantBits = singleExpShift+1;
59351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
59451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        binExp -= singleExpBias;
59551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // call the routine that actually does all the hard work.
59651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        dtoa( binExp, ((long)fractBits)<<(expShift-singleExpShift), nSignificantBits );
59751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
59851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
59951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private void
60051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    dtoa( int binExp, long fractBits, int nSignificantBits )
60151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    {
60251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int     nFractBits; // number of significant bits of fractBits;
60351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int     nTinyBits;  // number of these to the right of the point.
60451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int     decExp;
60551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
60651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Examine number. Determine if it is an easy case,
60751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // which we can do pretty trivially using float/long conversion,
60851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // or whether we must do real work.
60951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        nFractBits = countBits( fractBits );
61051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        nTinyBits = Math.max( 0, nFractBits - binExp - 1 );
61151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( binExp <= maxSmallBinExp && binExp >= minSmallBinExp ){
61251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // Look more closely at the number to decide if,
61351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // with scaling by 10^nTinyBits, the result will fit in
61451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // a long.
61551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ( (nTinyBits < long5pow.length) && ((nFractBits + n5bits[nTinyBits]) < 64 ) ){
61651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                /*
61751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * We can do this:
61851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * take the fraction bits, which are normalized.
61951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * (a) nTinyBits == 0: Shift left or right appropriately
62051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 *     to align the binary point at the extreme right, i.e.
62151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 *     where a long int point is expected to be. The integer
62251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 *     result is easily converted to a string.
62351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * (b) nTinyBits > 0: Shift right by expShift-nFractBits,
62451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 *     which effectively converts to long and scales by
62551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 *     2^nTinyBits. Then multiply by 5^nTinyBits to
62651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 *     complete the scaling. We know this won't overflow
62751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 *     because we just counted the number of bits necessary
62851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 *     in the result. The integer you get from this can
62951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 *     then be converted to a string pretty easily.
63051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 */
63151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                long halfULP;
63251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if ( nTinyBits == 0 ) {
63351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ( binExp > nSignificantBits ){
63451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        halfULP = 1L << ( binExp-nSignificantBits-1);
63551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    } else {
63651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        halfULP = 0L;
63751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
63851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ( binExp >= expShift ){
63951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        fractBits <<= (binExp-expShift);
64051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    } else {
64151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        fractBits >>>= (expShift-binExp) ;
64251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
64351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    developLongDigits( 0, fractBits, halfULP );
64451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    return;
64551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
64651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                /*
64751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * The following causes excess digits to be printed
64851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * out in the single-float case. Our manipulation of
64951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * halfULP here is apparently not correct. If we
65051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * better understand how this works, perhaps we can
65151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * use this special case again. But for the time being,
65251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * we do not.
65351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * else {
65451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 *     fractBits >>>= expShift+1-nFractBits;
65551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 *     fractBits *= long5pow[ nTinyBits ];
65651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 *     halfULP = long5pow[ nTinyBits ] >> (1+nSignificantBits-nFractBits);
65751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 *     developLongDigits( -nTinyBits, fractBits, halfULP );
65851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 *     return;
65951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * }
66051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 */
66151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
66251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
66351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        /*
66451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * This is the hard case. We are going to compute large positive
66551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * integers B and S and integer decExp, s.t.
66651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         *      d = ( B / S ) * 10^decExp
66751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         *      1 <= B / S < 10
66851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * Obvious choices are:
66951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         *      decExp = floor( log10(d) )
67051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         *      B      = d * 2^nTinyBits * 10^max( 0, -decExp )
67151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         *      S      = 10^max( 0, decExp) * 2^nTinyBits
67251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * (noting that nTinyBits has already been forced to non-negative)
67351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * I am also going to compute a large positive integer
67451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         *      M      = (1/2^nSignificantBits) * 2^nTinyBits * 10^max( 0, -decExp )
67551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * i.e. M is (1/2) of the ULP of d, scaled like B.
67651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * When we iterate through dividing B/S and picking off the
67751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * quotient bits, we will know when to stop when the remainder
67851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * is <= M.
67951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         *
68051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * We keep track of powers of 2 and powers of 5.
68151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         */
68251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
68351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        /*
68451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * Estimate decimal exponent. (If it is small-ish,
68551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * we could double-check.)
68651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         *
68751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * First, scale the mantissa bits such that 1 <= d2 < 2.
68851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * We are then going to estimate
68951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         *          log10(d2) ~=~  (d2-1.5)/1.5 + log(1.5)
69051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * and so we can estimate
69151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         *      log10(d) ~=~ log10(d2) + binExp * log10(2)
69251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * take the floor and call it decExp.
69351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * FIXME -- use more precise constants here. It costs no more.
69451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         */
69551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        double d2 = Double.longBitsToDouble(
69651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            expOne | ( fractBits &~ fractHOB ) );
69751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        decExp = (int)Math.floor(
69851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            (d2-1.5D)*0.289529654D + 0.176091259 + (double)binExp * 0.301029995663981 );
69951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int B2, B5; // powers of 2 and powers of 5, respectively, in B
70051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int S2, S5; // powers of 2 and powers of 5, respectively, in S
70151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int M2, M5; // powers of 2 and powers of 5, respectively, in M
70251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int Bbits; // binary digits needed to represent B, approx.
70351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int tenSbits; // binary digits needed to represent 10*S, approx.
70451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        FDBigInt Sval, Bval, Mval;
70551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
70651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        B5 = Math.max( 0, -decExp );
70751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        B2 = B5 + nTinyBits + binExp;
70851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
70951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        S5 = Math.max( 0, decExp );
71051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        S2 = S5 + nTinyBits;
71151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
71251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        M5 = B5;
71351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        M2 = B2 - nSignificantBits;
71451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
71551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        /*
71651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * the long integer fractBits contains the (nFractBits) interesting
71751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * bits from the mantissa of d ( hidden 1 added if necessary) followed
71851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * by (expShift+1-nFractBits) zeros. In the interest of compactness,
71951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * I will shift out those zeros before turning fractBits into a
72051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * FDBigInt. The resulting whole number will be
72151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         *      d * 2^(nFractBits-1-binExp).
72251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         */
72351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        fractBits >>>= (expShift+1-nFractBits);
72451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        B2 -= nFractBits-1;
72551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int common2factor = Math.min( B2, S2 );
72651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        B2 -= common2factor;
72751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        S2 -= common2factor;
72851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        M2 -= common2factor;
72951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
73051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        /*
73151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * HACK!! For exact powers of two, the next smallest number
73251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * is only half as far away as we think (because the meaning of
73351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * ULP changes at power-of-two bounds) for this reason, we
73451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * hack M2. Hope this works.
73551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         */
73651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( nFractBits == 1 )
73751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            M2 -= 1;
73851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
73951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( M2 < 0 ){
74051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // oops.
74151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // since we cannot scale M down far enough,
74251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // we must scale the other values up.
74351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            B2 -= M2;
74451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            S2 -= M2;
74551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            M2 =  0;
74651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
74751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        /*
74851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * Construct, Scale, iterate.
74951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * Some day, we'll write a stopping test that takes
75051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * account of the assymetry of the spacing of floating-point
75151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * numbers below perfect powers of 2
75251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * 26 Sept 96 is not that day.
75351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * So we use a symmetric test.
75451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         */
75551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        char digits[] = this.digits = new char[18];
75651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int  ndigit = 0;
75751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        boolean low, high;
75851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        long lowDigitDifference;
75951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int  q;
76051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
76151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        /*
76251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * Detect the special cases where all the numbers we are about
76351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * to compute will fit in int or long integers.
76451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * In these cases, we will avoid doing FDBigInt arithmetic.
76551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * We use the same algorithms, except that we "normalize"
76651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * our FDBigInts before iterating. This is to make division easier,
76751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * as it makes our fist guess (quotient of high-order words)
76851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * more accurate!
76951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         *
77051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * Some day, we'll write a stopping test that takes
77151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * account of the assymetry of the spacing of floating-point
77251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * numbers below perfect powers of 2
77351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * 26 Sept 96 is not that day.
77451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * So we use a symmetric test.
77551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         */
77651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        Bbits = nFractBits + B2 + (( B5 < n5bits.length )? n5bits[B5] : ( B5*3 ));
77751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        tenSbits = S2+1 + (( (S5+1) < n5bits.length )? n5bits[(S5+1)] : ( (S5+1)*3 ));
77851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( Bbits < 64 && tenSbits < 64){
77951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ( Bbits < 32 && tenSbits < 32){
78051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // wa-hoo! They're all ints!
78151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                int b = ((int)fractBits * small5pow[B5] ) << B2;
78251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                int s = small5pow[S5] << S2;
78351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                int m = small5pow[M5] << M2;
78451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                int tens = s * 10;
78551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                /*
78651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * Unroll the first iteration. If our decExp estimate
78751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * was too high, our first quotient will be zero. In this
78851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * case, we discard it and decrement decExp.
78951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 */
79051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                ndigit = 0;
79151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                q = b / s;
79251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                b = 10 * ( b % s );
79351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                m *= 10;
79451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                low  = (b <  m );
79551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                high = (b+m > tens );
79651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                assert q < 10 : q; // excessively large digit
79751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if ( (q == 0) && ! high ){
79851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // oops. Usually ignore leading zero.
79951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    decExp--;
80051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else {
80151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    digits[ndigit++] = (char)('0' + q);
80251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
80351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                /*
80451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * HACK! Java spec sez that we always have at least
80551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * one digit after the . in either F- or E-form output.
80651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * Thus we will need more than one digit if we're using
80751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * E-form
80851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 */
80951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (! (form == Form.COMPATIBLE && -3 < decExp && decExp < 8)) {
81051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    high = low = false;
81151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
81251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                while( ! low && ! high ){
81351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    q = b / s;
81451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    b = 10 * ( b % s );
81551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    m *= 10;
81651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    assert q < 10 : q; // excessively large digit
81751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ( m > 0L ){
81851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        low  = (b <  m );
81951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        high = (b+m > tens );
82051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    } else {
82151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // hack -- m might overflow!
82251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // in this case, it is certainly > b,
82351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // which won't
82451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // and b+m > tens, too, since that has overflowed
82551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // either!
82651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        low = true;
82751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        high = true;
82851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
82951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    digits[ndigit++] = (char)('0' + q);
83051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
83151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                lowDigitDifference = (b<<1) - tens;
83251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else {
83351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // still good! they're all longs!
83451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                long b = (fractBits * long5pow[B5] ) << B2;
83551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                long s = long5pow[S5] << S2;
83651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                long m = long5pow[M5] << M2;
83751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                long tens = s * 10L;
83851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                /*
83951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * Unroll the first iteration. If our decExp estimate
84051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * was too high, our first quotient will be zero. In this
84151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * case, we discard it and decrement decExp.
84251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 */
84351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                ndigit = 0;
84451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                q = (int) ( b / s );
84551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                b = 10L * ( b % s );
84651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                m *= 10L;
84751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                low  = (b <  m );
84851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                high = (b+m > tens );
84951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                assert q < 10 : q; // excessively large digit
85051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if ( (q == 0) && ! high ){
85151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // oops. Usually ignore leading zero.
85251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    decExp--;
85351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else {
85451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    digits[ndigit++] = (char)('0' + q);
85551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
85651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                /*
85751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * HACK! Java spec sez that we always have at least
85851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * one digit after the . in either F- or E-form output.
85951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * Thus we will need more than one digit if we're using
86051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * E-form
86151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 */
86251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (! (form == Form.COMPATIBLE && -3 < decExp && decExp < 8)) {
86351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    high = low = false;
86451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
86551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                while( ! low && ! high ){
86651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    q = (int) ( b / s );
86751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    b = 10 * ( b % s );
86851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    m *= 10;
86951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    assert q < 10 : q;  // excessively large digit
87051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ( m > 0L ){
87151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        low  = (b <  m );
87251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        high = (b+m > tens );
87351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    } else {
87451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // hack -- m might overflow!
87551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // in this case, it is certainly > b,
87651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // which won't
87751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // and b+m > tens, too, since that has overflowed
87851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // either!
87951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        low = true;
88051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        high = true;
88151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
88251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    digits[ndigit++] = (char)('0' + q);
88351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
88451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                lowDigitDifference = (b<<1) - tens;
88551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
88651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
88751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            FDBigInt tenSval;
88851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            int  shiftBias;
88951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
89051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            /*
89151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * We really must do FDBigInt arithmetic.
89251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * Fist, construct our FDBigInt initial values.
89351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             */
89451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            Bval = multPow52( new FDBigInt( fractBits  ), B5, B2 );
89551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            Sval = constructPow52( S5, S2 );
89651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            Mval = constructPow52( M5, M2 );
89751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
89851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
89951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // normalize so that division works better
90051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            Bval.lshiftMe( shiftBias = Sval.normalizeMe() );
90151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            Mval.lshiftMe( shiftBias );
90251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            tenSval = Sval.mult( 10 );
90351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            /*
90451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * Unroll the first iteration. If our decExp estimate
90551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * was too high, our first quotient will be zero. In this
90651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * case, we discard it and decrement decExp.
90751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             */
90851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            ndigit = 0;
90951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            q = Bval.quoRemIteration( Sval );
91051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            Mval = Mval.mult( 10 );
91151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            low  = (Bval.cmp( Mval ) < 0);
91251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            high = (Bval.add( Mval ).cmp( tenSval ) > 0 );
91351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            assert q < 10 : q; // excessively large digit
91451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ( (q == 0) && ! high ){
91551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // oops. Usually ignore leading zero.
91651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                decExp--;
91751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else {
91851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                digits[ndigit++] = (char)('0' + q);
91951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
92051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            /*
92151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * HACK! Java spec sez that we always have at least
92251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * one digit after the . in either F- or E-form output.
92351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * Thus we will need more than one digit if we're using
92451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * E-form
92551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             */
92651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (! (form == Form.COMPATIBLE && -3 < decExp && decExp < 8)) {
92751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                high = low = false;
92851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
92951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            while( ! low && ! high ){
93051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                q = Bval.quoRemIteration( Sval );
93151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                Mval = Mval.mult( 10 );
93251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                assert q < 10 : q;  // excessively large digit
93351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                low  = (Bval.cmp( Mval ) < 0);
93451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                high = (Bval.add( Mval ).cmp( tenSval ) > 0 );
93551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                digits[ndigit++] = (char)('0' + q);
93651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
93751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ( high && low ){
93851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                Bval.lshiftMe(1);
93951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                lowDigitDifference = Bval.cmp(tenSval);
94051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else
94151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                lowDigitDifference = 0L; // this here only for flow analysis!
94251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
94351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.decExponent = decExp+1;
94451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.digits = digits;
94551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.nDigits = ndigit;
94651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        /*
94751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * Last digit gets rounded based on stopping condition.
94851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         */
94951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( high ){
95051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ( low ){
95151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if ( lowDigitDifference == 0L ){
95251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // it's a tie!
95351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // choose based on which digits we like.
95451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ( (digits[nDigits-1]&1) != 0 ) roundup();
95551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else if ( lowDigitDifference > 0 ){
95651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    roundup();
95751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
95851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else {
95951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                roundup();
96051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
96151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
96251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
96351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
96451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public String
96551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    toString(){
96651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // most brain-dead version
96751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        StringBuffer result = new StringBuffer( nDigits+8 );
96851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( isNegative ){ result.append( '-' ); }
96951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( isExceptional ){
97051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            result.append( digits, 0, nDigits );
97151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
97251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            result.append( "0.");
97351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            result.append( digits, 0, nDigits );
97451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            result.append('e');
97551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            result.append( decExponent );
97651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
97751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return new String(result);
97851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
97951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
98051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // returns the exponent before rounding
98151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public int getExponent() {
98251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return decExponent - 1;
98351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
98451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
98551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // returns the exponent after rounding has been done by applyPrecision
98651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public int getExponentRounded() {
98751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return decExponentRounded - 1;
98851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
98951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
99051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public int getChars(char[] result) {
99151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        assert nDigits <= 19 : nDigits; // generous bound on size of nDigits
99251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int i = 0;
99351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (isNegative) { result[0] = '-'; i = 1; }
99451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (isExceptional) {
99551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            System.arraycopy(digits, 0, result, i, nDigits);
99651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            i += nDigits;
99751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
99851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            char digits [] = this.digits;
99951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            int exp = decExponent;
100051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            switch (form) {
100151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            case COMPATIBLE:
100251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                break;
100351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            case DECIMAL_FLOAT:
100451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                exp = checkExponent(decExponent + precision);
100551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                digits = applyPrecision(decExponent + precision);
100651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                break;
100751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            case SCIENTIFIC:
100851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                exp = checkExponent(precision + 1);
100951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                digits = applyPrecision(precision + 1);
101051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                break;
101151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            case GENERAL:
101251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                exp = checkExponent(precision);
101351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                digits = applyPrecision(precision);
101451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // adjust precision to be the number of digits to right of decimal
101551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // the real exponent to be output is actually exp - 1, not exp
101651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (exp - 1 < -4 || exp - 1 >= precision) {
101751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    form = Form.SCIENTIFIC;
101851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    precision--;
101951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else {
102051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    form = Form.DECIMAL_FLOAT;
102151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    precision = precision - exp;
102251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
102351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                break;
102451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            default:
102551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                assert false;
102651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
102751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            decExponentRounded = exp;
102851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
102951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (exp > 0
103051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                && ((form == Form.COMPATIBLE && (exp < 8))
103151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    || (form == Form.DECIMAL_FLOAT)))
103251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            {
103351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // print digits.digits.
103451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                int charLength = Math.min(nDigits, exp);
103551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                System.arraycopy(digits, 0, result, i, charLength);
103651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                i += charLength;
103751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (charLength < exp) {
103851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    charLength = exp-charLength;
103951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    for (int nz = 0; nz < charLength; nz++)
104051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        result[i++] = '0';
104151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // Do not append ".0" for formatted floats since the user
104251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // may request that it be omitted. It is added as necessary
104351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // by the Formatter.
104451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (form == Form.COMPATIBLE) {
104551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        result[i++] = '.';
104651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        result[i++] = '0';
104751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
104851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else {
104951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // Do not append ".0" for formatted floats since the user
105051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // may request that it be omitted. It is added as necessary
105151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // by the Formatter.
105251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (form == Form.COMPATIBLE) {
105351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        result[i++] = '.';
105451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        if (charLength < nDigits) {
105551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            int t = Math.min(nDigits - charLength, precision);
105651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            System.arraycopy(digits, charLength, result, i, t);
105751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            i += t;
105851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        } else {
105951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            result[i++] = '0';
106051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
106151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    } else {
106251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        int t = Math.min(nDigits - charLength, precision);
106351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        if (t > 0) {
106451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            result[i++] = '.';
106551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            System.arraycopy(digits, charLength, result, i, t);
106651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            i += t;
106751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
106851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
106951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
107051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else if (exp <= 0
107151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                       && ((form == Form.COMPATIBLE && exp > -3)
107251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                       || (form == Form.DECIMAL_FLOAT)))
107351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            {
107451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // print 0.0* digits
107551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                result[i++] = '0';
107651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (exp != 0) {
107751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // write '0' s before the significant digits
107851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    int t = Math.min(-exp, precision);
107951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (t > 0) {
108051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        result[i++] = '.';
108151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        for (int nz = 0; nz < t; nz++)
108251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            result[i++] = '0';
108351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
108451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
108551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                int t = Math.min(digits.length, precision + exp);
108651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (t > 0) {
108751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (i == 1)
108851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        result[i++] = '.';
108951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // copy only when significant digits are within the precision
109051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    System.arraycopy(digits, 0, result, i, t);
109151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    i += t;
109251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
109351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else {
109451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                result[i++] = digits[0];
109551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (form == Form.COMPATIBLE) {
109651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    result[i++] = '.';
109751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (nDigits > 1) {
109851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        System.arraycopy(digits, 1, result, i, nDigits-1);
109951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        i += nDigits-1;
110051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    } else {
110151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        result[i++] = '0';
110251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
110351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    result[i++] = 'E';
110451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else {
110551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (nDigits > 1) {
110651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        int t = Math.min(nDigits -1, precision);
110751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        if (t > 0) {
110851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            result[i++] = '.';
110951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            System.arraycopy(digits, 1, result, i, t);
111051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            i += t;
111151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
111251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
111351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    result[i++] = 'e';
111451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
111551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                int e;
111651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (exp <= 0) {
111751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    result[i++] = '-';
111851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    e = -exp+1;
111951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else {
112051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (form != Form.COMPATIBLE)
112151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        result[i++] = '+';
112251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    e = exp-1;
112351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
112451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // decExponent has 1, 2, or 3, digits
112551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (e <= 9) {
112651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (form != Form.COMPATIBLE)
112751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        result[i++] = '0';
112851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    result[i++] = (char)(e+'0');
112951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else if (e <= 99) {
113051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    result[i++] = (char)(e/10 +'0');
113151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    result[i++] = (char)(e%10 + '0');
113251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else {
113351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    result[i++] = (char)(e/100+'0');
113451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    e %= 100;
113551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    result[i++] = (char)(e/10+'0');
113651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    result[i++] = (char)(e%10 + '0');
113751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
113851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
113951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
114051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return i;
114151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
114251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
114351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // Per-thread buffer for string/stringbuffer conversion
114451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static ThreadLocal perThreadBuffer = new ThreadLocal() {
114551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            protected synchronized Object initialValue() {
114651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return new char[26];
114751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
114851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        };
114951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
115051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /*
115151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Take a FormattedFloatingDecimal, which we presumably just scanned in,
115251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * and find out what its value is, as a double.
115351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
115451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * AS A SIDE EFFECT, SET roundDir TO INDICATE PREFERRED
115551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * ROUNDING DIRECTION in case the result is really destined
115651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * for a single-precision float.
115751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
115851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
115951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public strictfp double doubleValue(){
116051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int     kDigits = Math.min( nDigits, maxDecimalDigits+1 );
116151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        long    lValue;
116251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        double  dValue;
116351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        double  rValue, tValue;
116451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
116551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // First, check for NaN and Infinity values
116651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if(digits == infinity || digits == notANumber) {
116751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if(digits == notANumber)
116851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return Double.NaN;
116951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            else
117051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return (isNegative?Double.NEGATIVE_INFINITY:Double.POSITIVE_INFINITY);
117151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
117251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        else {
117351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (mustSetRoundDir) {
117451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                roundDir = 0;
117551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
117651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            /*
117751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * convert the lead kDigits to a long integer.
117851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             */
117951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // (special performance hack: start to do it using int)
118051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            int iValue = (int)digits[0]-(int)'0';
118151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            int iDigits = Math.min( kDigits, intDecimalDigits );
118251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            for ( int i=1; i < iDigits; i++ ){
118351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                iValue = iValue*10 + (int)digits[i]-(int)'0';
118451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
118551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            lValue = (long)iValue;
118651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            for ( int i=iDigits; i < kDigits; i++ ){
118751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                lValue = lValue*10L + (long)((int)digits[i]-(int)'0');
118851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
118951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            dValue = (double)lValue;
119051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            int exp = decExponent-kDigits;
119151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            /*
119251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * lValue now contains a long integer with the value of
119351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * the first kDigits digits of the number.
119451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * dValue contains the (double) of the same.
119551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             */
119651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
119751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ( nDigits <= maxDecimalDigits ){
119851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                /*
119951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * possibly an easy case.
120051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * We know that the digits can be represented
120151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * exactly. And if the exponent isn't too outrageous,
120251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * the whole thing can be done with one operation,
120351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * thus one rounding error.
120451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * Note that all our constructors trim all leading and
120551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * trailing zeros, so simple values (including zero)
120651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * will always end up here
120751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 */
120851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (exp == 0 || dValue == 0.0)
120951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    return (isNegative)? -dValue : dValue; // small floating integer
121051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                else if ( exp >= 0 ){
121151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ( exp <= maxSmallTen ){
121251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        /*
121351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * Can get the answer with one operation,
121451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * thus one roundoff.
121551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         */
121651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        rValue = dValue * small10pow[exp];
121751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        if ( mustSetRoundDir ){
121851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            tValue = rValue / small10pow[exp];
121951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            roundDir = ( tValue ==  dValue ) ? 0
122051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                :( tValue < dValue ) ? 1
122151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                : -1;
122251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
122351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        return (isNegative)? -rValue : rValue;
122451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
122551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    int slop = maxDecimalDigits - kDigits;
122651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ( exp <= maxSmallTen+slop ){
122751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        /*
122851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * We can multiply dValue by 10^(slop)
122951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * and it is still "small" and exact.
123051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * Then we can multiply by 10^(exp-slop)
123151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * with one rounding.
123251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         */
123351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        dValue *= small10pow[slop];
123451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        rValue = dValue * small10pow[exp-slop];
123551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
123651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        if ( mustSetRoundDir ){
123751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            tValue = rValue / small10pow[exp-slop];
123851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            roundDir = ( tValue ==  dValue ) ? 0
123951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                :( tValue < dValue ) ? 1
124051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                : -1;
124151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
124251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        return (isNegative)? -rValue : rValue;
124351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
124451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    /*
124551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     * Else we have a hard case with a positive exp.
124651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     */
124751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else {
124851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ( exp >= -maxSmallTen ){
124951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        /*
125051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * Can get the answer in one division.
125151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         */
125251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        rValue = dValue / small10pow[-exp];
125351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        tValue = rValue * small10pow[-exp];
125451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        if ( mustSetRoundDir ){
125551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            roundDir = ( tValue ==  dValue ) ? 0
125651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                :( tValue < dValue ) ? 1
125751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                : -1;
125851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
125951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        return (isNegative)? -rValue : rValue;
126051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
126151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    /*
126251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     * Else we have a hard case with a negative exp.
126351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     */
126451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
126551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
126651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
126751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            /*
126851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * Harder cases:
126951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * The sum of digits plus exponent is greater than
127051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * what we think we can do with one error.
127151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             *
127251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * Start by approximating the right answer by,
127351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * naively, scaling by powers of 10.
127451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             */
127551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ( exp > 0 ){
127651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if ( decExponent > maxDecimalExponent+1 ){
127751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    /*
127851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     * Lets face it. This is going to be
127951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     * Infinity. Cut to the chase.
128051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     */
128151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    return (isNegative)? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
128251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
128351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if ( (exp&15) != 0 ){
128451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    dValue *= small10pow[exp&15];
128551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
128651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if ( (exp>>=4) != 0 ){
128751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    int j;
128851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    for( j = 0; exp > 1; j++, exp>>=1 ){
128951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        if ( (exp&1)!=0)
129051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            dValue *= big10pow[j];
129151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
129251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    /*
129351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     * The reason for the weird exp > 1 condition
129451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     * in the above loop was so that the last multiply
129551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     * would get unrolled. We handle it here.
129651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     * It could overflow.
129751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     */
129851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    double t = dValue * big10pow[j];
129951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ( Double.isInfinite( t ) ){
130051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        /*
130151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * It did overflow.
130251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * Look more closely at the result.
130351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * If the exponent is just one too large,
130451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * then use the maximum finite as our estimate
130551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * value. Else call the result infinity
130651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * and punt it.
130751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * ( I presume this could happen because
130851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * rounding forces the result here to be
130951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * an ULP or two larger than
131051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * Double.MAX_VALUE ).
131151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         */
131251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        t = dValue / 2.0;
131351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        t *= big10pow[j];
131451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        if ( Double.isInfinite( t ) ){
131551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            return (isNegative)? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
131651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
131751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        t = Double.MAX_VALUE;
131851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
131951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    dValue = t;
132051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
132151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else if ( exp < 0 ){
132251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                exp = -exp;
132351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if ( decExponent < minDecimalExponent-1 ){
132451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    /*
132551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     * Lets face it. This is going to be
132651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     * zero. Cut to the chase.
132751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     */
132851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    return (isNegative)? -0.0 : 0.0;
132951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
133051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if ( (exp&15) != 0 ){
133151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    dValue /= small10pow[exp&15];
133251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
133351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if ( (exp>>=4) != 0 ){
133451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    int j;
133551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    for( j = 0; exp > 1; j++, exp>>=1 ){
133651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        if ( (exp&1)!=0)
133751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            dValue *= tiny10pow[j];
133851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
133951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    /*
134051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     * The reason for the weird exp > 1 condition
134151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     * in the above loop was so that the last multiply
134251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     * would get unrolled. We handle it here.
134351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     * It could underflow.
134451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     */
134551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    double t = dValue * tiny10pow[j];
134651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ( t == 0.0 ){
134751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        /*
134851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * It did underflow.
134951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * Look more closely at the result.
135051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * If the exponent is just one too small,
135151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * then use the minimum finite as our estimate
135251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * value. Else call the result 0.0
135351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * and punt it.
135451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * ( I presume this could happen because
135551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * rounding forces the result here to be
135651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * an ULP or two less than
135751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * Double.MIN_VALUE ).
135851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         */
135951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        t = dValue * 2.0;
136051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        t *= tiny10pow[j];
136151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        if ( t == 0.0 ){
136251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            return (isNegative)? -0.0 : 0.0;
136351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
136451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        t = Double.MIN_VALUE;
136551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
136651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    dValue = t;
136751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
136851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
136951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
137051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            /*
137151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * dValue is now approximately the result.
137251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * The hard part is adjusting it, by comparison
137351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * with FDBigInt arithmetic.
137451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * Formulate the EXACT big-number result as
137551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * bigD0 * 10^exp
137651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             */
137751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            FDBigInt bigD0 = new FDBigInt( lValue, digits, kDigits, nDigits );
137851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            exp   = decExponent - nDigits;
137951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
138051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            correctionLoop:
138151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            while(true){
138251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                /* AS A SIDE EFFECT, THIS METHOD WILL SET THE INSTANCE VARIABLES
138351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * bigIntExp and bigIntNBits
138451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 */
138551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                FDBigInt bigB = doubleToBigInt( dValue );
138651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
138751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                /*
138851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * Scale bigD, bigB appropriately for
138951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * big-integer operations.
139051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * Naively, we multipy by powers of ten
139151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * and powers of two. What we actually do
139251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * is keep track of the powers of 5 and
139351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * powers of 2 we would use, then factor out
139451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * common divisors before doing the work.
139551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 */
139651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                int B2, B5; // powers of 2, 5 in bigB
139751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                int     D2, D5; // powers of 2, 5 in bigD
139851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                int Ulp2;   // powers of 2 in halfUlp.
139951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if ( exp >= 0 ){
140051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    B2 = B5 = 0;
140151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    D2 = D5 = exp;
140251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else {
140351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    B2 = B5 = -exp;
140451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    D2 = D5 = 0;
140551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
140651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if ( bigIntExp >= 0 ){
140751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    B2 += bigIntExp;
140851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else {
140951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    D2 -= bigIntExp;
141051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
141151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                Ulp2 = B2;
141251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // shift bigB and bigD left by a number s. t.
141351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // halfUlp is still an integer.
141451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                int hulpbias;
141551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if ( bigIntExp+bigIntNBits <= -expBias+1 ){
141651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // This is going to be a denormalized number
141751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // (if not actually zero).
141851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // half an ULP is at 2^-(expBias+expShift+1)
141951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    hulpbias = bigIntExp+ expBias + expShift;
142051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else {
142151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    hulpbias = expShift + 2 - bigIntNBits;
142251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
142351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                B2 += hulpbias;
142451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                D2 += hulpbias;
142551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // if there are common factors of 2, we might just as well
142651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // factor them out, as they add nothing useful.
142751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                int common2 = Math.min( B2, Math.min( D2, Ulp2 ) );
142851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                B2 -= common2;
142951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                D2 -= common2;
143051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                Ulp2 -= common2;
143151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // do multiplications by powers of 5 and 2
143251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                bigB = multPow52( bigB, B5, B2 );
143351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                FDBigInt bigD = multPow52( new FDBigInt( bigD0 ), D5, D2 );
143451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                //
143551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // to recap:
143651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // bigB is the scaled-big-int version of our floating-point
143751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // candidate.
143851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // bigD is the scaled-big-int version of the exact value
143951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // as we understand it.
144051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // halfUlp is 1/2 an ulp of bigB, except for special cases
144151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // of exact powers of 2
144251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                //
144351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // the plan is to compare bigB with bigD, and if the difference
144451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // is less than halfUlp, then we're satisfied. Otherwise,
144551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // use the ratio of difference to halfUlp to calculate a fudge
144651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // factor to add to the floating value, then go 'round again.
144751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                //
144851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                FDBigInt diff;
144951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                int cmpResult;
145051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                boolean overvalue;
145151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if ( (cmpResult = bigB.cmp( bigD ) ) > 0 ){
145251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    overvalue = true; // our candidate is too big.
145351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    diff = bigB.sub( bigD );
145451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ( (bigIntNBits == 1) && (bigIntExp > -expBias) ){
145551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // candidate is a normalized exact power of 2 and
145651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // is too big. We will be subtracting.
145751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // For our purposes, ulp is the ulp of the
145851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // next smaller range.
145951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        Ulp2 -= 1;
146051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        if ( Ulp2 < 0 ){
146151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            // rats. Cannot de-scale ulp this far.
146251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            // must scale diff in other direction.
146351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            Ulp2 = 0;
146451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            diff.lshiftMe( 1 );
146551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
146651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
146751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else if ( cmpResult < 0 ){
146851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    overvalue = false; // our candidate is too small.
146951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    diff = bigD.sub( bigB );
147051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else {
147151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // the candidate is exactly right!
147251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // this happens with surprising fequency
147351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    break correctionLoop;
147451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
147551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                FDBigInt halfUlp = constructPow52( B5, Ulp2 );
147651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if ( (cmpResult = diff.cmp( halfUlp ) ) < 0 ){
147751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // difference is small.
147851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // this is close enough
147951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (mustSetRoundDir) {
148051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        roundDir = overvalue ? -1 : 1;
148151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
148251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    break correctionLoop;
148351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else if ( cmpResult == 0 ){
148451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // difference is exactly half an ULP
148551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // round to some other value maybe, then finish
148651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    dValue += 0.5*ulp( dValue, overvalue );
148751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // should check for bigIntNBits == 1 here??
148851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (mustSetRoundDir) {
148951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        roundDir = overvalue ? -1 : 1;
149051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
149151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    break correctionLoop;
149251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else {
149351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // difference is non-trivial.
149451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // could scale addend by ratio of difference to
149551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // halfUlp here, if we bothered to compute that difference.
149651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // Most of the time ( I hope ) it is about 1 anyway.
149751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    dValue += ulp( dValue, overvalue );
149851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ( dValue == 0.0 || dValue == Double.POSITIVE_INFINITY )
149951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        break correctionLoop; // oops. Fell off end of range.
150051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    continue; // try again.
150151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
150251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
150351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
150451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return (isNegative)? -dValue : dValue;
150551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
150651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
150751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
150851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /*
150951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Take a FormattedFloatingDecimal, which we presumably just scanned in,
151051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * and find out what its value is, as a float.
151151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * This is distinct from doubleValue() to avoid the extremely
151251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * unlikely case of a double rounding error, wherein the converstion
151351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * to double has one rounding error, and the conversion of that double
151451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * to a float has another rounding error, IN THE WRONG DIRECTION,
151551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * ( because of the preference to a zero low-order bit ).
151651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
151751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
151851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public strictfp float floatValue(){
151951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int     kDigits = Math.min( nDigits, singleMaxDecimalDigits+1 );
152051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int     iValue;
152151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        float   fValue;
152251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
152351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // First, check for NaN and Infinity values
152451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if(digits == infinity || digits == notANumber) {
152551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if(digits == notANumber)
152651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return Float.NaN;
152751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            else
152851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return (isNegative?Float.NEGATIVE_INFINITY:Float.POSITIVE_INFINITY);
152951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
153051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        else {
153151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            /*
153251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * convert the lead kDigits to an integer.
153351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             */
153451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            iValue = (int)digits[0]-(int)'0';
153551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            for ( int i=1; i < kDigits; i++ ){
153651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                iValue = iValue*10 + (int)digits[i]-(int)'0';
153751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
153851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            fValue = (float)iValue;
153951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            int exp = decExponent-kDigits;
154051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            /*
154151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * iValue now contains an integer with the value of
154251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * the first kDigits digits of the number.
154351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * fValue contains the (float) of the same.
154451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             */
154551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
154651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ( nDigits <= singleMaxDecimalDigits ){
154751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                /*
154851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * possibly an easy case.
154951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * We know that the digits can be represented
155051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * exactly. And if the exponent isn't too outrageous,
155151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * the whole thing can be done with one operation,
155251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * thus one rounding error.
155351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * Note that all our constructors trim all leading and
155451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * trailing zeros, so simple values (including zero)
155551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * will always end up here.
155651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 */
155751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (exp == 0 || fValue == 0.0f)
155851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    return (isNegative)? -fValue : fValue; // small floating integer
155951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                else if ( exp >= 0 ){
156051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ( exp <= singleMaxSmallTen ){
156151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        /*
156251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * Can get the answer with one operation,
156351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * thus one roundoff.
156451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         */
156551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        fValue *= singleSmall10pow[exp];
156651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        return (isNegative)? -fValue : fValue;
156751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
156851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    int slop = singleMaxDecimalDigits - kDigits;
156951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ( exp <= singleMaxSmallTen+slop ){
157051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        /*
157151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * We can multiply dValue by 10^(slop)
157251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * and it is still "small" and exact.
157351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * Then we can multiply by 10^(exp-slop)
157451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * with one rounding.
157551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         */
157651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        fValue *= singleSmall10pow[slop];
157751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        fValue *= singleSmall10pow[exp-slop];
157851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        return (isNegative)? -fValue : fValue;
157951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
158051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    /*
158151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     * Else we have a hard case with a positive exp.
158251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     */
158351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else {
158451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ( exp >= -singleMaxSmallTen ){
158551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        /*
158651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * Can get the answer in one division.
158751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         */
158851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        fValue /= singleSmall10pow[-exp];
158951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        return (isNegative)? -fValue : fValue;
159051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
159151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    /*
159251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     * Else we have a hard case with a negative exp.
159351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     */
159451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
159551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else if ( (decExponent >= nDigits) && (nDigits+decExponent <= maxDecimalDigits) ){
159651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                /*
159751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * In double-precision, this is an exact floating integer.
159851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * So we can compute to double, then shorten to float
159951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * with one round, and get the right answer.
160051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 *
160151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * First, finish accumulating digits.
160251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * Then convert that integer to a double, multiply
160351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * by the appropriate power of ten, and convert to float.
160451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 */
160551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                long lValue = (long)iValue;
160651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                for ( int i=kDigits; i < nDigits; i++ ){
160751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    lValue = lValue*10L + (long)((int)digits[i]-(int)'0');
160851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
160951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                double dValue = (double)lValue;
161051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                exp = decExponent-nDigits;
161151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                dValue *= small10pow[exp];
161251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                fValue = (float)dValue;
161351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return (isNegative)? -fValue : fValue;
161451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
161551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
161651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            /*
161751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * Harder cases:
161851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * The sum of digits plus exponent is greater than
161951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * what we think we can do with one error.
162051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             *
162151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * Start by weeding out obviously out-of-range
162251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * results, then convert to double and go to
162351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * common hard-case code.
162451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             */
162551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ( decExponent > singleMaxDecimalExponent+1 ){
162651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                /*
162751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * Lets face it. This is going to be
162851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * Infinity. Cut to the chase.
162951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 */
163051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return (isNegative)? Float.NEGATIVE_INFINITY : Float.POSITIVE_INFINITY;
163151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else if ( decExponent < singleMinDecimalExponent-1 ){
163251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                /*
163351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * Lets face it. This is going to be
163451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * zero. Cut to the chase.
163551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 */
163651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return (isNegative)? -0.0f : 0.0f;
163751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
163851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
163951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            /*
164051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * Here, we do 'way too much work, but throwing away
164151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * our partial results, and going and doing the whole
164251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * thing as double, then throwing away half the bits that computes
164351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * when we convert back to float.
164451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             *
164551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * The alternative is to reproduce the whole multiple-precision
164651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * algorythm for float precision, or to try to parameterize it
164751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * for common usage. The former will take about 400 lines of code,
164851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * and the latter I tried without success. Thus the semi-hack
164951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * answer here.
165051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             */
165151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            mustSetRoundDir = !fromHex;
165251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            double dValue = doubleValue();
165351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return stickyRound( dValue );
165451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
165551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
165651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
165751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
165851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /*
165951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * All the positive powers of 10 that can be
166051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * represented exactly in double/float.
166151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
166251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static final double small10pow[] = {
166351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        1.0e0,
166451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        1.0e1, 1.0e2, 1.0e3, 1.0e4, 1.0e5,
166551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        1.0e6, 1.0e7, 1.0e8, 1.0e9, 1.0e10,
166651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        1.0e11, 1.0e12, 1.0e13, 1.0e14, 1.0e15,
166751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        1.0e16, 1.0e17, 1.0e18, 1.0e19, 1.0e20,
166851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        1.0e21, 1.0e22
166951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    };
167051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
167151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static final float singleSmall10pow[] = {
167251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        1.0e0f,
167351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        1.0e1f, 1.0e2f, 1.0e3f, 1.0e4f, 1.0e5f,
167451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        1.0e6f, 1.0e7f, 1.0e8f, 1.0e9f, 1.0e10f
167551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    };
167651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
167751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static final double big10pow[] = {
167851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        1e16, 1e32, 1e64, 1e128, 1e256 };
167951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static final double tiny10pow[] = {
168051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        1e-16, 1e-32, 1e-64, 1e-128, 1e-256 };
168151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
168251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static final int maxSmallTen = small10pow.length-1;
168351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static final int singleMaxSmallTen = singleSmall10pow.length-1;
168451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
168551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static final int small5pow[] = {
168651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        1,
168751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5,
168851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5*5,
168951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5*5*5,
169051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5*5*5*5,
169151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5*5*5*5*5,
169251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5*5*5*5*5*5,
169351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5*5*5*5*5*5*5,
169451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5*5*5*5*5*5*5*5,
169551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5*5*5*5*5*5*5*5*5,
169651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5*5*5*5*5*5*5*5*5*5,
169751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5*5*5*5*5*5*5*5*5*5*5,
169851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5*5*5*5*5*5*5*5*5*5*5*5,
169951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5*5*5*5*5*5*5*5*5*5*5*5*5
170051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    };
170151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
170251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
170351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static final long long5pow[] = {
170451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        1L,
170551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L,
170651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5,
170751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5,
170851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5*5,
170951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5*5*5,
171051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5*5*5*5,
171151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5*5*5*5*5,
171251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5*5*5*5*5*5,
171351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5*5*5*5*5*5*5,
171451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5*5*5*5*5*5*5*5,
171551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5*5*5*5*5*5*5*5*5,
171651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5*5*5*5*5*5*5*5*5*5,
171751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5*5*5*5*5*5*5*5*5*5*5,
171851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5*5*5*5*5*5*5*5*5*5*5*5,
171951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
172051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
172151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
172251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
172351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
172451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
172551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
172651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
172751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
172851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
172951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
173051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
173151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    };
173251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
173351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // approximately ceil( log2( long5pow[i] ) )
173451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static final int n5bits[] = {
173551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        0,
173651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        3,
173751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5,
173851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        7,
173951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        10,
174051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        12,
174151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        14,
174251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        17,
174351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        19,
174451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        21,
174551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        24,
174651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        26,
174751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        28,
174851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        31,
174951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        33,
175051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        35,
175151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        38,
175251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        40,
175351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        42,
175451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        45,
175551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        47,
175651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        49,
175751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        52,
175851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        54,
175951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        56,
176051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        59,
176151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        61,
176251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    };
176351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
176451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static final char infinity[] = { 'I', 'n', 'f', 'i', 'n', 'i', 't', 'y' };
176551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static final char notANumber[] = { 'N', 'a', 'N' };
176651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static final char zero[] = { '0', '0', '0', '0', '0', '0', '0', '0' };
176751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski}
1768