19524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak   /*
251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Copyright (c) 1996, 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
269524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniakpackage java.lang;
2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.misc.FpUtils;
299524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniakimport sun.misc.FDBigInt;
3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.misc.DoubleConsts;
3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.misc.FloatConsts;
3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.regex.*;
3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
349524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniakpublic class FloatingDecimal {
3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    boolean     isExceptional;
3651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    boolean     isNegative;
3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    int         decExponent;
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
4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /*
4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Constants of the implementation
4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Most are IEEE-754 related.
4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * (There are more really boring constants at the end.)
5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final long   signMask = 0x8000000000000000L;
5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final long   expMask  = 0x7ff0000000000000L;
5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final long   fractMask= ~(signMask|expMask);
5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final int    expShift = 52;
5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final int    expBias  = 1023;
5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final long   fractHOB = ( 1L<<expShift ); // assumed High-Order bit
5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final long   expOne   = ((long)expBias)<<expShift; // exponent of 1.0
5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final int    maxSmallBinExp = 62;
5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final int    minSmallBinExp = -( 63 / 3 );
6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final int    maxDecimalDigits = 15;
6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final int    maxDecimalExponent = 308;
6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final int    minDecimalExponent = -324;
6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final int    bigDecimalExponent = 324; // i.e. abs(minDecimalExponent)
6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final long   highbyte = 0xff00000000000000L;
6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final long   highbit  = 0x8000000000000000L;
6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final long   lowbytes = ~highbyte;
6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final int    singleSignMask =    0x80000000;
7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final int    singleExpMask  =    0x7f800000;
7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final int    singleFractMask =   ~(singleSignMask|singleExpMask);
7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final int    singleExpShift  =   23;
7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final int    singleFractHOB  =   1<<singleExpShift;
7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final int    singleExpBias   =   127;
7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final int    singleMaxDecimalDigits = 7;
7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final int    singleMaxDecimalExponent = 38;
7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final int    singleMinDecimalExponent = -45;
7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static final int    intDecimalDigits = 9;
8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /*
8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * count number of bits from high-order 1 bit to low-order 1 bit,
8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * inclusive.
8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static int
8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    countBits( long v ){
8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        //
8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // the strategy is to shift until we get a non-zero sign bit
8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // then shift until we have no bits left, counting the difference.
9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // we do byte shifting as a hack. Hope it helps.
9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        //
9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( v == 0L ) return 0;
9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        while ( ( v & highbyte ) == 0L ){
9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            v <<= 8;
9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        while ( v > 0L ) { // i.e. while ((v&highbit) == 0L )
9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            v <<= 1;
9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int n = 0;
10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        while (( v & lowbytes ) != 0L ){
10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            v <<= 8;
10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            n += 8;
10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        while ( v != 0L ){
10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            v <<= 1;
10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            n += 1;
10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return n;
11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /*
11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Keep big powers of 5 handy for future reference.
11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static FDBigInt b5p[];
11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static synchronized FDBigInt
11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    big5pow( int p ){
12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        assert p >= 0 : p; // negative power of 5
12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( b5p == null ){
12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            b5p = new FDBigInt[ p+1 ];
12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }else if (b5p.length <= p ){
12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            FDBigInt t[] = new FDBigInt[ p+1 ];
12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            System.arraycopy( b5p, 0, t, 0, b5p.length );
12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            b5p = t;
12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( b5p[p] != null )
12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return b5p[p];
13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        else if ( p < small5pow.length )
13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return b5p[p] = new FDBigInt( small5pow[p] );
13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        else if ( p < long5pow.length )
13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return b5p[p] = new FDBigInt( long5pow[p] );
13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        else {
13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // construct the value.
13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // recursively.
13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            int q, r;
13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // in order to compute 5^p,
13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // compute its square root, 5^(p/2) and square.
14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // or, let q = p / 2, r = p -q, then
14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // 5^p = 5^(q+r) = 5^q * 5^r
14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            q = p >> 1;
14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            r = p - q;
14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            FDBigInt bigq =  b5p[q];
14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ( bigq == null )
14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                bigq = big5pow ( q );
14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ( r < small5pow.length ){
14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return (b5p[p] = bigq.mult( small5pow[r] ) );
14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }else{
15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                FDBigInt bigr = b5p[ r ];
15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if ( bigr == null )
15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    bigr = big5pow( r );
15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return (b5p[p] = bigq.mult( bigr ) );
15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    //
15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // a common operation
16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    //
16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static FDBigInt
16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    multPow52( FDBigInt v, int p5, int p2 ){
16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( p5 != 0 ){
16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ( p5 < small5pow.length ){
16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                v = v.mult( small5pow[p5] );
16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else {
16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                v = v.mult( big5pow( p5 ) );
16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( p2 != 0 ){
17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            v.lshiftMe( p2 );
17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
17351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return v;
17451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
17551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    //
17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // another common operation
17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    //
17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static FDBigInt
18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    constructPow52( int p5, int p2 ){
18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        FDBigInt v = new FDBigInt( big5pow( p5 ) );
18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( p2 != 0 ){
18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            v.lshiftMe( p2 );
18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return v;
18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /*
18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Make a floating double into a FDBigInt.
19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * This could also be structured as a FDBigInt
19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * constructor, but we'd have to build a lot of knowledge
19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * about floating-point representation into it, and we don't want to.
19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * AS A SIDE EFFECT, THIS METHOD WILL SET THE INSTANCE VARIABLES
19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * bigIntExp and bigIntNBits
19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private FDBigInt
19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    doubleToBigInt( double dval ){
20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        long lbits = Double.doubleToLongBits( dval ) & ~signMask;
20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int binexp = (int)(lbits >>> expShift);
20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        lbits &= fractMask;
20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( binexp > 0 ){
20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            lbits |= fractHOB;
20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            assert lbits != 0L : lbits; // doubleToBigInt(0.0)
20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            binexp +=1;
20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            while ( (lbits & fractHOB ) == 0L){
20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                lbits <<= 1;
21051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                binexp -= 1;
21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        binexp -= expBias;
21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int nbits = countBits( lbits );
21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        /*
21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * We now know where the high-order 1 bit is,
21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * and we know how many there are.
21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         */
21951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int lowOrderZeros = expShift+1-nbits;
22051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        lbits >>>= lowOrderZeros;
22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
22251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        bigIntExp = binexp+1-nbits;
22351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        bigIntNBits = nbits;
22451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return new FDBigInt( lbits );
22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
22751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /*
22851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Compute a number that is the ULP of the given value,
22951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * for purposes of addition/subtraction. Generally easy.
23051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * More difficult if subtracting and the argument
23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * is a normalized a power of 2, as the ULP changes at these points.
23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static double ulp( double dval, boolean subtracting ){
23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        long lbits = Double.doubleToLongBits( dval ) & ~signMask;
23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int binexp = (int)(lbits >>> expShift);
23651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        double ulpval;
23751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( subtracting && ( binexp >= expShift ) && ((lbits&fractMask) == 0L) ){
23851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // for subtraction from normalized, powers of 2,
23951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // use next-smaller exponent
24051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            binexp -= 1;
24151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( binexp > expShift ){
24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            ulpval = Double.longBitsToDouble( ((long)(binexp-expShift))<<expShift );
24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else if ( binexp == 0 ){
24551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            ulpval = Double.MIN_VALUE;
24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            ulpval = Double.longBitsToDouble( 1L<<(binexp-1) );
24851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
24951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( subtracting ) ulpval = - ulpval;
25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
25151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return ulpval;
25251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
25351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
25451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /*
25551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Round a double to a float.
25651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * In addition to the fraction bits of the double,
25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * look at the class instance variable roundDir,
25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * which should help us avoid double-rounding error.
25951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * roundDir was set in hardValueOf if the estimate was
26051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * close enough, but not exact. It tells us which direction
26151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * of rounding is preferred.
26251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
26351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    float
26451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    stickyRound( double dval ){
26551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        long lbits = Double.doubleToLongBits( dval );
26651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        long binexp = lbits & expMask;
26751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( binexp == 0L || binexp == expMask ){
26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // what we have here is special.
26951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // don't worry, the right thing will happen.
27051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return (float) dval;
27151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
27251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        lbits += (long)roundDir; // hack-o-matic.
27351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return (float)Double.longBitsToDouble( lbits );
27451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
27551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
27651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
27751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /*
27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * This is the easy subcase --
27951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * all the significant bits, after scaling, are held in lvalue.
28051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * negSign and decExponent tell us what processing and scaling
28151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * has already been done. Exceptional cases have already been
28251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * stripped out.
28351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * In particular:
28451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * lvalue is a finite number (not Inf, nor NaN)
28551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * lvalue > 0L (not zero, nor negative).
28651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
28751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * The only reason that we develop the digits here, rather than
28851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * calling on Long.toString() is that we can do it a little faster,
28951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * and besides want to treat trailing 0s specially. If Long.toString
29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * changes, we should re-evaluate this strategy!
29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private void
29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    developLongDigits( int decExponent, long lvalue, long insignificant ){
29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        char digits[];
29551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int  ndigits;
29651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int  digitno;
29751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int  c;
29851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        //
29951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Discard non-significant low-order bits, while rounding,
30051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // up to insignificant value.
30151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int i;
30251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        for ( i = 0; insignificant >= 10L; i++ )
30351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            insignificant /= 10L;
30451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( i != 0 ){
30551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            long pow10 = long5pow[i] << i; // 10^i == 5^i * 2^i;
30651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            long residue = lvalue % pow10;
30751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            lvalue /= pow10;
30851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            decExponent += i;
30951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ( residue >= (pow10>>1) ){
31051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // round up based on the low-order bits we're discarding
31151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                lvalue++;
31251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
31351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
31451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( lvalue <= Integer.MAX_VALUE ){
31551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            assert lvalue > 0L : lvalue; // lvalue <= 0
31651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // even easier subcase!
31751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // can do int arithmetic rather than long!
31851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            int  ivalue = (int)lvalue;
31951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            ndigits = 10;
32051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            digits = (char[])(perThreadBuffer.get());
32151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            digitno = ndigits-1;
32251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            c = ivalue%10;
32351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            ivalue /= 10;
32451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            while ( c == 0 ){
32551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                decExponent++;
32651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                c = ivalue%10;
32751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                ivalue /= 10;
32851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
32951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            while ( ivalue != 0){
33051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                digits[digitno--] = (char)(c+'0');
33151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                decExponent++;
33251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                c = ivalue%10;
33351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                ivalue /= 10;
33451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
33551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            digits[digitno] = (char)(c+'0');
33651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
33751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // same algorithm as above (same bugs, too )
33851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // but using long arithmetic.
33951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            ndigits = 20;
34051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            digits = (char[])(perThreadBuffer.get());
34151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            digitno = ndigits-1;
34251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            c = (int)(lvalue%10L);
34351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            lvalue /= 10L;
34451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            while ( c == 0 ){
34551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                decExponent++;
34651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                c = (int)(lvalue%10L);
34751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                lvalue /= 10L;
34851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
34951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            while ( lvalue != 0L ){
35051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                digits[digitno--] = (char)(c+'0');
35151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                decExponent++;
35251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                c = (int)(lvalue%10L);
35351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                lvalue /= 10;
35451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
35551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            digits[digitno] = (char)(c+'0');
35651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
35751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        char result [];
35851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        ndigits -= digitno;
35951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        result = new char[ ndigits ];
36051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        System.arraycopy( digits, digitno, result, 0, ndigits );
36151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.digits = result;
36251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.decExponent = decExponent+1;
36351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.nDigits = ndigits;
36451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
36551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
36651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    //
36751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // add one to the least significant digit.
36851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // in the unlikely event there is a carry out,
36951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // deal with it.
37051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // assert that this will only happen where there
37151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // is only one digit, e.g. (float)1e-44 seems to do it.
37251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    //
37351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private void
37451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    roundup(){
37551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int i;
37651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int q = digits[ i = (nDigits-1)];
37751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( q == '9' ){
37851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            while ( q == '9' && i > 0 ){
37951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                digits[i] = '0';
38051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                q = digits[--i];
38151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
38251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ( q == '9' ){
38351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // carryout! High-order 1, rest 0s, larger exp.
38451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                decExponent += 1;
38551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                digits[0] = '1';
38651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return;
38751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
38851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // else fall through.
38951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
39051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        digits[i] = (char)(q+1);
39151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
39251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
3939524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak    private FloatingDecimal() {}
3949524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak
3959524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak    private static final ThreadLocal<FloatingDecimal> TL_INSTANCE = new ThreadLocal<FloatingDecimal>() {
3969524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak        @Override protected FloatingDecimal initialValue() {
3979524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak            return new FloatingDecimal();
3989524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak        }
3999524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak    };
4009524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak    public static FloatingDecimal getThreadLocalInstance() {
4019524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak        return TL_INSTANCE.get();
4029524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak    }
4039524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak
40451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /*
4059524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak     * FIRST IMPORTANT LOAD: DOUBLE
40651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
4079524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak    public FloatingDecimal loadDouble(double d) {
40851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        long    dBits = Double.doubleToLongBits( d );
40951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        long    fractBits;
41051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int     binExp;
41151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int     nSignificantBits;
41251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
4139524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak        mustSetRoundDir = false;
4149524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak        fromHex = false;
4159524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak        roundDir = 0;
4169524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak
41751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // discover and delete sign
41851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( (dBits&signMask) != 0 ){
41951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            isNegative = true;
42051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            dBits ^= signMask;
42151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
42251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            isNegative = false;
42351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
42451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Begin to unpack
42551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Discover obvious special cases of NaN and Infinity.
42651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        binExp = (int)( (dBits&expMask) >> expShift );
42751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        fractBits = dBits&fractMask;
42851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( binExp == (int)(expMask>>expShift) ) {
42951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            isExceptional = true;
43051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ( fractBits == 0L ){
43151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                digits =  infinity;
43251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else {
43351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                digits = notANumber;
43451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                isNegative = false; // NaN has no sign!
43551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
43651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            nDigits = digits.length;
4379524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak            return this;
43851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
43951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        isExceptional = false;
44051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Finish unpacking
44151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Normalize denormalized numbers.
44251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Insert assumed high-order bit for normalized numbers.
44351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Subtract exponent bias.
44451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( binExp == 0 ){
44551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ( fractBits == 0L ){
44651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // not a denorm, just a 0!
44751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                decExponent = 0;
44851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                digits = zero;
44951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                nDigits = 1;
4509524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak                return this;
45151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
45251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            while ( (fractBits&fractHOB) == 0L ){
45351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                fractBits <<= 1;
45451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                binExp -= 1;
45551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
45651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            nSignificantBits = expShift + binExp +1; // recall binExp is  - shift count.
45751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            binExp += 1;
45851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
45951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            fractBits |= fractHOB;
46051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            nSignificantBits = expShift+1;
46151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
46251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        binExp -= expBias;
46351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // call the routine that actually does all the hard work.
46451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        dtoa( binExp, fractBits, nSignificantBits );
4659524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak        return this;
46651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
46751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
46851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /*
4699524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak     * SECOND IMPORTANT LOAD: SINGLE
47051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
4719524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak    public FloatingDecimal loadFloat(float f) {
47251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int     fBits = Float.floatToIntBits( f );
47351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int     fractBits;
47451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int     binExp;
47551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int     nSignificantBits;
47651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
4779524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak        mustSetRoundDir = false;
4789524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak        fromHex = false;
4799524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak        roundDir = 0;
4809524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak
48151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // discover and delete sign
48251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( (fBits&singleSignMask) != 0 ){
48351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            isNegative = true;
48451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            fBits ^= singleSignMask;
48551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
48651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            isNegative = false;
48751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
48851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Begin to unpack
48951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Discover obvious special cases of NaN and Infinity.
49051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        binExp = (int)( (fBits&singleExpMask) >> singleExpShift );
49151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        fractBits = fBits&singleFractMask;
49251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( binExp == (int)(singleExpMask>>singleExpShift) ) {
49351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            isExceptional = true;
49451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ( fractBits == 0L ){
49551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                digits =  infinity;
49651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else {
49751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                digits = notANumber;
49851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                isNegative = false; // NaN has no sign!
49951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
50051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            nDigits = digits.length;
5019524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak            return this;
50251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
50351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        isExceptional = false;
50451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Finish unpacking
50551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Normalize denormalized numbers.
50651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Insert assumed high-order bit for normalized numbers.
50751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Subtract exponent bias.
50851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( binExp == 0 ){
50951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ( fractBits == 0 ){
51051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // not a denorm, just a 0!
51151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                decExponent = 0;
51251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                digits = zero;
51351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                nDigits = 1;
5149524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak                return this;
51551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
51651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            while ( (fractBits&singleFractHOB) == 0 ){
51751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                fractBits <<= 1;
51851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                binExp -= 1;
51951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
52051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            nSignificantBits = singleExpShift + binExp +1; // recall binExp is  - shift count.
52151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            binExp += 1;
52251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
52351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            fractBits |= singleFractHOB;
52451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            nSignificantBits = singleExpShift+1;
52551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
52651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        binExp -= singleExpBias;
52751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // call the routine that actually does all the hard work.
52851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        dtoa( binExp, ((long)fractBits)<<(expShift-singleExpShift), nSignificantBits );
5299524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak        return this;
53051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
53151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
53251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private void
53351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    dtoa( int binExp, long fractBits, int nSignificantBits )
53451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    {
53551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int     nFractBits; // number of significant bits of fractBits;
53651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int     nTinyBits;  // number of these to the right of the point.
53751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int     decExp;
53851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
53951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Examine number. Determine if it is an easy case,
54051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // which we can do pretty trivially using float/long conversion,
54151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // or whether we must do real work.
54251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        nFractBits = countBits( fractBits );
54351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        nTinyBits = Math.max( 0, nFractBits - binExp - 1 );
54451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( binExp <= maxSmallBinExp && binExp >= minSmallBinExp ){
54551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // Look more closely at the number to decide if,
54651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // with scaling by 10^nTinyBits, the result will fit in
54751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // a long.
54851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ( (nTinyBits < long5pow.length) && ((nFractBits + n5bits[nTinyBits]) < 64 ) ){
54951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                /*
55051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * We can do this:
55151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * take the fraction bits, which are normalized.
55251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * (a) nTinyBits == 0: Shift left or right appropriately
55351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 *     to align the binary point at the extreme right, i.e.
55451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 *     where a long int point is expected to be. The integer
55551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 *     result is easily converted to a string.
55651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * (b) nTinyBits > 0: Shift right by expShift-nFractBits,
55751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 *     which effectively converts to long and scales by
55851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 *     2^nTinyBits. Then multiply by 5^nTinyBits to
55951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 *     complete the scaling. We know this won't overflow
56051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 *     because we just counted the number of bits necessary
56151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 *     in the result. The integer you get from this can
56251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 *     then be converted to a string pretty easily.
56351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 */
56451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                long halfULP;
56551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if ( nTinyBits == 0 ) {
56651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ( binExp > nSignificantBits ){
56751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        halfULP = 1L << ( binExp-nSignificantBits-1);
56851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    } else {
56951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        halfULP = 0L;
57051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
57151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ( binExp >= expShift ){
57251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        fractBits <<= (binExp-expShift);
57351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    } else {
57451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        fractBits >>>= (expShift-binExp) ;
57551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
57651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    developLongDigits( 0, fractBits, halfULP );
57751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    return;
57851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
57951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                /*
58051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * The following causes excess digits to be printed
58151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * out in the single-float case. Our manipulation of
58251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * halfULP here is apparently not correct. If we
58351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * better understand how this works, perhaps we can
58451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * use this special case again. But for the time being,
58551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * we do not.
58651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * else {
58751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 *     fractBits >>>= expShift+1-nFractBits;
58851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 *     fractBits *= long5pow[ nTinyBits ];
58951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 *     halfULP = long5pow[ nTinyBits ] >> (1+nSignificantBits-nFractBits);
59051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 *     developLongDigits( -nTinyBits, fractBits, halfULP );
59151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 *     return;
59251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * }
59351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 */
59451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
59551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
59651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        /*
59751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * This is the hard case. We are going to compute large positive
59851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * integers B and S and integer decExp, s.t.
59951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         *      d = ( B / S ) * 10^decExp
60051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         *      1 <= B / S < 10
60151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * Obvious choices are:
60251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         *      decExp = floor( log10(d) )
60351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         *      B      = d * 2^nTinyBits * 10^max( 0, -decExp )
60451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         *      S      = 10^max( 0, decExp) * 2^nTinyBits
60551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * (noting that nTinyBits has already been forced to non-negative)
60651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * I am also going to compute a large positive integer
60751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         *      M      = (1/2^nSignificantBits) * 2^nTinyBits * 10^max( 0, -decExp )
60851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * i.e. M is (1/2) of the ULP of d, scaled like B.
60951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * When we iterate through dividing B/S and picking off the
61051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * quotient bits, we will know when to stop when the remainder
61151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * is <= M.
61251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         *
61351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * We keep track of powers of 2 and powers of 5.
61451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         */
61551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
61651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        /*
61751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * Estimate decimal exponent. (If it is small-ish,
61851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * we could double-check.)
61951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         *
62051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * First, scale the mantissa bits such that 1 <= d2 < 2.
62151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * We are then going to estimate
62251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         *          log10(d2) ~=~  (d2-1.5)/1.5 + log(1.5)
62351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * and so we can estimate
62451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         *      log10(d) ~=~ log10(d2) + binExp * log10(2)
62551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * take the floor and call it decExp.
62651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * FIXME -- use more precise constants here. It costs no more.
62751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         */
62851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        double d2 = Double.longBitsToDouble(
62951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            expOne | ( fractBits &~ fractHOB ) );
63051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        decExp = (int)Math.floor(
63151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            (d2-1.5D)*0.289529654D + 0.176091259 + (double)binExp * 0.301029995663981 );
63251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int B2, B5; // powers of 2 and powers of 5, respectively, in B
63351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int S2, S5; // powers of 2 and powers of 5, respectively, in S
63451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int M2, M5; // powers of 2 and powers of 5, respectively, in M
63551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int Bbits; // binary digits needed to represent B, approx.
63651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int tenSbits; // binary digits needed to represent 10*S, approx.
63751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        FDBigInt Sval, Bval, Mval;
63851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
63951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        B5 = Math.max( 0, -decExp );
64051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        B2 = B5 + nTinyBits + binExp;
64151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
64251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        S5 = Math.max( 0, decExp );
64351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        S2 = S5 + nTinyBits;
64451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
64551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        M5 = B5;
64651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        M2 = B2 - nSignificantBits;
64751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
64851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        /*
64951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * the long integer fractBits contains the (nFractBits) interesting
65051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * bits from the mantissa of d ( hidden 1 added if necessary) followed
65151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * by (expShift+1-nFractBits) zeros. In the interest of compactness,
65251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * I will shift out those zeros before turning fractBits into a
65351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * FDBigInt. The resulting whole number will be
65451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         *      d * 2^(nFractBits-1-binExp).
65551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         */
65651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        fractBits >>>= (expShift+1-nFractBits);
65751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        B2 -= nFractBits-1;
65851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int common2factor = Math.min( B2, S2 );
65951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        B2 -= common2factor;
66051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        S2 -= common2factor;
66151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        M2 -= common2factor;
66251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
66351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        /*
66451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * HACK!! For exact powers of two, the next smallest number
66551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * is only half as far away as we think (because the meaning of
66651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * ULP changes at power-of-two bounds) for this reason, we
66751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * hack M2. Hope this works.
66851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         */
66951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( nFractBits == 1 )
67051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            M2 -= 1;
67151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
67251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( M2 < 0 ){
67351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // oops.
67451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // since we cannot scale M down far enough,
67551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // we must scale the other values up.
67651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            B2 -= M2;
67751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            S2 -= M2;
67851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            M2 =  0;
67951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
68051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        /*
68151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * Construct, Scale, iterate.
68251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * Some day, we'll write a stopping test that takes
68351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * account of the asymmetry of the spacing of floating-point
68451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * numbers below perfect powers of 2
68551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * 26 Sept 96 is not that day.
68651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * So we use a symmetric test.
68751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         */
68851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        char digits[] = this.digits = new char[18];
68951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int  ndigit = 0;
69051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        boolean low, high;
69151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        long lowDigitDifference;
69251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int  q;
69351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
69451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        /*
69551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * Detect the special cases where all the numbers we are about
69651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * to compute will fit in int or long integers.
69751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * In these cases, we will avoid doing FDBigInt arithmetic.
69851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * We use the same algorithms, except that we "normalize"
69951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * our FDBigInts before iterating. This is to make division easier,
70051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * as it makes our fist guess (quotient of high-order words)
70151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * more accurate!
70251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         *
70351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * Some day, we'll write a stopping test that takes
70451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * account of the asymmetry of the spacing of floating-point
70551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * numbers below perfect powers of 2
70651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * 26 Sept 96 is not that day.
70751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * So we use a symmetric test.
70851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         */
70951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        Bbits = nFractBits + B2 + (( B5 < n5bits.length )? n5bits[B5] : ( B5*3 ));
71051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        tenSbits = S2+1 + (( (S5+1) < n5bits.length )? n5bits[(S5+1)] : ( (S5+1)*3 ));
71151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( Bbits < 64 && tenSbits < 64){
71251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ( Bbits < 32 && tenSbits < 32){
71351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // wa-hoo! They're all ints!
71451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                int b = ((int)fractBits * small5pow[B5] ) << B2;
71551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                int s = small5pow[S5] << S2;
71651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                int m = small5pow[M5] << M2;
71751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                int tens = s * 10;
71851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                /*
71951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * Unroll the first iteration. If our decExp estimate
72051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * was too high, our first quotient will be zero. In this
72151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * case, we discard it and decrement decExp.
72251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 */
72351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                ndigit = 0;
72451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                q = b / s;
72551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                b = 10 * ( b % s );
72651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                m *= 10;
72751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                low  = (b <  m );
72851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                high = (b+m > tens );
72951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                assert q < 10 : q; // excessively large digit
73051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if ( (q == 0) && ! high ){
73151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // oops. Usually ignore leading zero.
73251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    decExp--;
73351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else {
73451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    digits[ndigit++] = (char)('0' + q);
73551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
73651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                /*
73751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * HACK! Java spec sez that we always have at least
73851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * one digit after the . in either F- or E-form output.
73951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * Thus we will need more than one digit if we're using
74051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * E-form
74151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 */
74251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if ( decExp < -3 || decExp >= 8 ){
74351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    high = low = false;
74451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
74551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                while( ! low && ! high ){
74651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    q = b / s;
74751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    b = 10 * ( b % s );
74851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    m *= 10;
74951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    assert q < 10 : q; // excessively large digit
75051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ( m > 0L ){
75151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        low  = (b <  m );
75251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        high = (b+m > tens );
75351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    } else {
75451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // hack -- m might overflow!
75551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // in this case, it is certainly > b,
75651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // which won't
75751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // and b+m > tens, too, since that has overflowed
75851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // either!
75951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        low = true;
76051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        high = true;
76151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
76251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    digits[ndigit++] = (char)('0' + q);
76351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
76451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                lowDigitDifference = (b<<1) - tens;
76551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else {
76651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // still good! they're all longs!
76751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                long b = (fractBits * long5pow[B5] ) << B2;
76851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                long s = long5pow[S5] << S2;
76951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                long m = long5pow[M5] << M2;
77051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                long tens = s * 10L;
77151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                /*
77251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * Unroll the first iteration. If our decExp estimate
77351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * was too high, our first quotient will be zero. In this
77451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * case, we discard it and decrement decExp.
77551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 */
77651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                ndigit = 0;
77751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                q = (int) ( b / s );
77851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                b = 10L * ( b % s );
77951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                m *= 10L;
78051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                low  = (b <  m );
78151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                high = (b+m > tens );
78251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                assert q < 10 : q; // excessively large digit
78351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if ( (q == 0) && ! high ){
78451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // oops. Usually ignore leading zero.
78551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    decExp--;
78651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else {
78751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    digits[ndigit++] = (char)('0' + q);
78851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
78951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                /*
79051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * HACK! Java spec sez that we always have at least
79151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * one digit after the . in either F- or E-form output.
79251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * Thus we will need more than one digit if we're using
79351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * E-form
79451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 */
79551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if ( decExp < -3 || decExp >= 8 ){
79651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    high = low = false;
79751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
79851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                while( ! low && ! high ){
79951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    q = (int) ( b / s );
80051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    b = 10 * ( b % s );
80151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    m *= 10;
80251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    assert q < 10 : q;  // excessively large digit
80351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ( m > 0L ){
80451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        low  = (b <  m );
80551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        high = (b+m > tens );
80651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    } else {
80751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // hack -- m might overflow!
80851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // in this case, it is certainly > b,
80951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // which won't
81051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // and b+m > tens, too, since that has overflowed
81151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // either!
81251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        low = true;
81351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        high = true;
81451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
81551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    digits[ndigit++] = (char)('0' + q);
81651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
81751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                lowDigitDifference = (b<<1) - tens;
81851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
81951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
82051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            FDBigInt tenSval;
82151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            int  shiftBias;
82251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
82351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            /*
82451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * We really must do FDBigInt arithmetic.
82551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * Fist, construct our FDBigInt initial values.
82651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             */
82751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            Bval = multPow52( new FDBigInt( fractBits  ), B5, B2 );
82851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            Sval = constructPow52( S5, S2 );
82951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            Mval = constructPow52( M5, M2 );
83051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
83151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
83251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // normalize so that division works better
83351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            Bval.lshiftMe( shiftBias = Sval.normalizeMe() );
83451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            Mval.lshiftMe( shiftBias );
83551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            tenSval = Sval.mult( 10 );
83651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            /*
83751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * Unroll the first iteration. If our decExp estimate
83851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * was too high, our first quotient will be zero. In this
83951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * case, we discard it and decrement decExp.
84051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             */
84151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            ndigit = 0;
84251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            q = Bval.quoRemIteration( Sval );
84351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            Mval = Mval.mult( 10 );
84451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            low  = (Bval.cmp( Mval ) < 0);
84551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            high = (Bval.add( Mval ).cmp( tenSval ) > 0 );
84651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            assert q < 10 : q; // excessively large digit
84751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ( (q == 0) && ! high ){
84851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // oops. Usually ignore leading zero.
84951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                decExp--;
85051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else {
85151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                digits[ndigit++] = (char)('0' + q);
85251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
85351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            /*
85451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * HACK! Java spec sez that we always have at least
85551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * one digit after the . in either F- or E-form output.
85651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * Thus we will need more than one digit if we're using
85751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * E-form
85851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             */
85951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ( decExp < -3 || decExp >= 8 ){
86051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                high = low = false;
86151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
86251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            while( ! low && ! high ){
86351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                q = Bval.quoRemIteration( Sval );
86451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                Mval = Mval.mult( 10 );
86551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                assert q < 10 : q;  // excessively large digit
86651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                low  = (Bval.cmp( Mval ) < 0);
86751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                high = (Bval.add( Mval ).cmp( tenSval ) > 0 );
86851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                digits[ndigit++] = (char)('0' + q);
86951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
87051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ( high && low ){
87151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                Bval.lshiftMe(1);
87251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                lowDigitDifference = Bval.cmp(tenSval);
87351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else
87451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                lowDigitDifference = 0L; // this here only for flow analysis!
87551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
87651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.decExponent = decExp+1;
87751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.digits = digits;
87851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.nDigits = ndigit;
87951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        /*
88051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * Last digit gets rounded based on stopping condition.
88151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         */
88251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( high ){
88351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ( low ){
88451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if ( lowDigitDifference == 0L ){
88551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // it's a tie!
88651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // choose based on which digits we like.
88751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ( (digits[nDigits-1]&1) != 0 ) roundup();
88851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else if ( lowDigitDifference > 0 ){
88951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    roundup();
89051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
89151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else {
89251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                roundup();
89351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
89451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
89551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
89651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
89751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public String
89851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    toString(){
89951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // most brain-dead version
90051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        StringBuffer result = new StringBuffer( nDigits+8 );
90151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( isNegative ){ result.append( '-' ); }
90251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ( isExceptional ){
90351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            result.append( digits, 0, nDigits );
90451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
90551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            result.append( "0.");
90651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            result.append( digits, 0, nDigits );
90751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            result.append('e');
90851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            result.append( decExponent );
90951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
91051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return new String(result);
91151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
91251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
91351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public String toJavaFormatString() {
91451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        char result[] = (char[])(perThreadBuffer.get());
91551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int i = getChars(result);
91651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return new String(result, 0, i);
91751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
91851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
91951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private int getChars(char[] result) {
92051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        assert nDigits <= 19 : nDigits; // generous bound on size of nDigits
92151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int i = 0;
92251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (isNegative) { result[0] = '-'; i = 1; }
92351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (isExceptional) {
92451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            System.arraycopy(digits, 0, result, i, nDigits);
92551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            i += nDigits;
92651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
92751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (decExponent > 0 && decExponent < 8) {
9289524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak                // case with digits.digits
92951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                int charLength = Math.min(nDigits, decExponent);
93051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                System.arraycopy(digits, 0, result, i, charLength);
93151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                i += charLength;
93251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (charLength < decExponent) {
93351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    charLength = decExponent-charLength;
93451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    System.arraycopy(zero, 0, result, i, charLength);
93551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    i += charLength;
93651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    result[i++] = '.';
93751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    result[i++] = '0';
93851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else {
93951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    result[i++] = '.';
94051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (charLength < nDigits) {
94151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        int t = nDigits - charLength;
94251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        System.arraycopy(digits, charLength, result, i, t);
94351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        i += t;
94451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    } else {
94551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        result[i++] = '0';
94651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
94751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
94851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else if (decExponent <=0 && decExponent > -3) {
9499524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak                // case with 0.digits
95051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                result[i++] = '0';
95151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                result[i++] = '.';
95251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (decExponent != 0) {
95351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    System.arraycopy(zero, 0, result, i, -decExponent);
95451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    i -= decExponent;
95551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
95651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                System.arraycopy(digits, 0, result, i, nDigits);
95751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                i += nDigits;
95851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else {
9599524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak                // case with digit.digitsEexponent
96051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                result[i++] = digits[0];
96151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                result[i++] = '.';
96251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (nDigits > 1) {
96351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    System.arraycopy(digits, 1, result, i, nDigits-1);
96451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    i += nDigits-1;
96551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else {
96651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    result[i++] = '0';
96751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
96851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                result[i++] = 'E';
96951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                int e;
97051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (decExponent <= 0) {
97151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    result[i++] = '-';
97251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    e = -decExponent+1;
97351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else {
97451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    e = decExponent-1;
97551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
97651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // decExponent has 1, 2, or 3, digits
97751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (e <= 9) {
97851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    result[i++] = (char)(e+'0');
97951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else if (e <= 99) {
98051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    result[i++] = (char)(e/10 +'0');
98151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    result[i++] = (char)(e%10 + '0');
98251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else {
98351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    result[i++] = (char)(e/100+'0');
98451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    e %= 100;
98551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    result[i++] = (char)(e/10+'0');
98651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    result[i++] = (char)(e%10 + '0');
98751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
98851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
98951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
99051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return i;
99151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
99251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
99351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // Per-thread buffer for string/stringbuffer conversion
99451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static ThreadLocal perThreadBuffer = new ThreadLocal() {
99551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            protected synchronized Object initialValue() {
99651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return new char[26];
99751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
99851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        };
99951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
10009524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak    public void appendTo(AbstractStringBuilder buf) {
10019524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak        if (isNegative) { buf.append('-'); }
10029524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak        if (isExceptional) {
10039524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak            buf.append(digits, 0 , nDigits);
10049524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak            return;
10059524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak        }
10069524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak        if (decExponent > 0 && decExponent < 8) {
10079524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak            // print digits.digits.
10089524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak            int charLength = Math.min(nDigits, decExponent);
10099524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak            buf.append(digits, 0 , charLength);
10109524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak            if (charLength < decExponent) {
10119524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak                charLength = decExponent-charLength;
10129524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak                buf.append(zero, 0 , charLength);
10139524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak                buf.append(".0");
10149524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak            } else {
10159524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak                buf.append('.');
10169524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak                if (charLength < nDigits) {
10179524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak                    buf.append(digits, charLength, nDigits - charLength);
10189524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak                } else {
10199524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak                    buf.append('0');
10209524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak                }
10219524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak            }
10229524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak        } else if (decExponent <=0 && decExponent > -3) {
10239524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak            buf.append("0.");
10249524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak            if (decExponent != 0) {
10259524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak                buf.append(zero, 0, -decExponent);
10269524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak            }
10279524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak            buf.append(digits, 0, nDigits);
10289524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak        } else {
10299524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak            buf.append(digits[0]);
10309524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak            buf.append('.');
10319524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak            if (nDigits > 1) {
10329524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak                buf.append(digits, 1, nDigits-1);
10339524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak            } else {
10349524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak                buf.append('0');
10359524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak            }
10369524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak            buf.append('E');
10379524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak            int e;
10389524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak            if (decExponent <= 0) {
10399524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak                buf.append('-');
10409524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak                e = -decExponent + 1;
10419524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak            } else {
10429524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak                e = decExponent - 1;
10439524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak            }
10449524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak            // decExponent has 1, 2, or 3, digits
10459524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak            if (e <= 9) {
10469524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak                buf.append((char)(e + '0'));
10479524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak            } else if (e <= 99) {
10489524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak                buf.append((char)(e/10 + '0'));
10499524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak                buf.append((char)(e%10 + '0'));
10509524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak            } else {
10519524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak                buf.append((char)(e/100 + '0'));
10529524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak                e %= 100;
10539524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak                buf.append((char)(e/10 + '0'));
10549524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak                buf.append((char)(e%10 + '0'));
10559524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak            }
10569524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak        }
105751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
105851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
10599524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak    public FloatingDecimal
106051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    readJavaFormatString( String in ) throws NumberFormatException {
106151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        boolean isNegative = false;
106251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        boolean signSeen   = false;
106351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int     decExp;
106451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        char    c;
106551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
106651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    parseNumber:
106751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        try{
106851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            in = in.trim(); // don't fool around with white space.
106951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            // throws NullPointerException if null
107051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            int l = in.length();
107151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ( l == 0 ) throw new NumberFormatException("empty String");
107251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            int i = 0;
107351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            switch ( c = in.charAt( i ) ){
107451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            case '-':
107551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                isNegative = true;
107651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                //FALLTHROUGH
107751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            case '+':
107851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                i++;
107951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                signSeen = true;
108051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
108151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
108251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // Check for NaN and Infinity strings
108351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            c = in.charAt(i);
108451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if(c == 'N' || c == 'I') { // possible NaN or infinity
108551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                boolean potentialNaN = false;
108651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                char targetChars[] = null;  // char array of "NaN" or "Infinity"
108751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
108851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if(c == 'N') {
108951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    targetChars = notANumber;
109051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    potentialNaN = true;
109151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else {
109251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    targetChars = infinity;
109351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
109451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
109551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // compare Input string to "NaN" or "Infinity"
109651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                int j = 0;
109751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                while(i < l && j < targetChars.length) {
109851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if(in.charAt(i) == targetChars[j]) {
109951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        i++; j++;
110051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
110151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    else // something is amiss, throw exception
110251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        break parseNumber;
110351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
110451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
110551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // For the candidate string to be a NaN or infinity,
110651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // all characters in input string and target char[]
110751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // must be matched ==> j must equal targetChars.length
110851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // and i must equal l
110951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if( (j == targetChars.length) && (i == l) ) { // return NaN or infinity
11109524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak                    return (potentialNaN ? loadDouble(Double.NaN) // NaN has no sign
11119524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak                            : loadDouble(isNegative?
111251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                                  Double.NEGATIVE_INFINITY:
111351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                                  Double.POSITIVE_INFINITY)) ;
111451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
111551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                else { // something went wrong, throw exception
111651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    break parseNumber;
111751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
111851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
111951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else if (c == '0')  { // check for hexadecimal floating-point number
112051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (l > i+1 ) {
112151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    char ch = in.charAt(i+1);
112251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (ch == 'x' || ch == 'X' ) // possible hex string
112351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        return parseHexString(in);
112451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
112551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }  // look for and process decimal floating-point string
112651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
112751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            char[] digits = new char[ l ];
112851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            int    nDigits= 0;
112951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            boolean decSeen = false;
113051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            int decPt = 0;
113151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            int nLeadZero = 0;
113251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            int nTrailZero= 0;
113351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        digitLoop:
113451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            while ( i < l ){
113551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                switch ( c = in.charAt( i ) ){
113651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                case '0':
113751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ( nDigits > 0 ){
113851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        nTrailZero += 1;
113951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    } else {
114051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        nLeadZero += 1;
114151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
114251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    break; // out of switch.
114351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                case '1':
114451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                case '2':
114551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                case '3':
114651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                case '4':
114751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                case '5':
114851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                case '6':
114951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                case '7':
115051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                case '8':
115151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                case '9':
115251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    while ( nTrailZero > 0 ){
115351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        digits[nDigits++] = '0';
115451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        nTrailZero -= 1;
115551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
115651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    digits[nDigits++] = c;
115751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    break; // out of switch.
115851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                case '.':
115951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ( decSeen ){
116051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // already saw one ., this is the 2nd.
116151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        throw new NumberFormatException("multiple points");
116251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
116351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    decPt = i;
116451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ( signSeen ){
116551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        decPt -= 1;
116651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
116751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    decSeen = true;
116851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    break; // out of switch.
116951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                default:
117051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    break digitLoop;
117151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
117251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                i++;
117351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
117451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            /*
117551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * At this point, we've scanned all the digits and decimal
117651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * point we're going to see. Trim off leading and trailing
117751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * zeros, which will just confuse us later, and adjust
117851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * our initial decimal exponent accordingly.
117951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * To review:
118051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * we have seen i total characters.
118151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * nLeadZero of them were zeros before any other digits.
118251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * nTrailZero of them were zeros after any other digits.
118351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * if ( decSeen ), then a . was seen after decPt characters
118451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * ( including leading zeros which have been discarded )
118551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * nDigits characters were neither lead nor trailing
118651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * zeros, nor point
118751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             */
118851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            /*
118951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * special hack: if we saw no non-zero digits, then the
119051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * answer is zero!
119151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * Unfortunately, we feel honor-bound to keep parsing!
119251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             */
119351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ( nDigits == 0 ){
119451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                digits = zero;
119551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                nDigits = 1;
119651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if ( nLeadZero == 0 ){
119751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // we saw NO DIGITS AT ALL,
119851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // not even a crummy 0!
119951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // this is not allowed.
120051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    break parseNumber; // go throw exception
120151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
120251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
120351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
120451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
120551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            /* Our initial exponent is decPt, adjusted by the number of
120651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * discarded zeros. Or, if there was no decPt,
120751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * then its just nDigits adjusted by discarded trailing zeros.
120851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             */
120951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ( decSeen ){
121051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                decExp = decPt - nLeadZero;
121151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else {
121251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                decExp = nDigits+nTrailZero;
121351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
121451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
121551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            /*
121651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * Look for 'e' or 'E' and an optionally signed integer.
121751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             */
121851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ( (i < l) &&  (((c = in.charAt(i) )=='e') || (c == 'E') ) ){
121951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                int expSign = 1;
122051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                int expVal  = 0;
122151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                int reallyBig = Integer.MAX_VALUE / 10;
122251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                boolean expOverflow = false;
122351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                switch( in.charAt(++i) ){
122451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                case '-':
122551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    expSign = -1;
122651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    //FALLTHROUGH
122751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                case '+':
122851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    i++;
122951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
123051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                int expAt = i;
123151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            expLoop:
123251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                while ( i < l  ){
123351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ( expVal >= reallyBig ){
123451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // the next character will cause integer
123551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // overflow.
123651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        expOverflow = true;
123751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
123851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    switch ( c = in.charAt(i++) ){
123951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    case '0':
124051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    case '1':
124151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    case '2':
124251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    case '3':
124351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    case '4':
124451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    case '5':
124551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    case '6':
124651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    case '7':
124751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    case '8':
124851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    case '9':
124951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        expVal = expVal*10 + ( (int)c - (int)'0' );
125051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        continue;
125151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    default:
125251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        i--;           // back up.
125351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        break expLoop; // stop parsing exponent.
125451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
125551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
125651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                int expLimit = bigDecimalExponent+nDigits+nTrailZero;
125751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if ( expOverflow || ( expVal > expLimit ) ){
125851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    //
125951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // The intent here is to end up with
126051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // infinity or zero, as appropriate.
126151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // The reason for yielding such a small decExponent,
126251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // rather than something intuitive such as
126351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // expSign*Integer.MAX_VALUE, is that this value
126451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // is subject to further manipulation in
126551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // doubleValue() and floatValue(), and I don't want
126651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // it to be able to cause overflow there!
126751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // (The only way we can get into trouble here is for
126851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // really outrageous nDigits+nTrailZero, such as 2 billion. )
126951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    //
127051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    decExp = expSign*expLimit;
127151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else {
127251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // this should not overflow, since we tested
127351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // for expVal > (MAX+N), where N >= abs(decExp)
127451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    decExp = decExp + expSign*expVal;
127551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
127651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
127751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // if we saw something not a digit ( or end of string )
127851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // after the [Ee][+-], without seeing any digits at all
127951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // this is certainly an error. If we saw some digits,
128051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // but then some trailing garbage, that might be ok.
128151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // so we just fall through in that case.
128251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // HUMBUG
128351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if ( i == expAt )
128451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    break parseNumber; // certainly bad
128551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
128651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            /*
128751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * We parsed everything we could.
128851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * If there are leftovers, then this is not good input!
128951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             */
129051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ( i < l &&
129151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                ((i != l - 1) ||
129251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                (in.charAt(i) != 'f' &&
129351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 in.charAt(i) != 'F' &&
129451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 in.charAt(i) != 'd' &&
129551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 in.charAt(i) != 'D'))) {
129651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                break parseNumber; // go throw exception
129751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
129851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
12999524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak            this.isNegative = isNegative;
13009524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak            this.decExponent = decExp;
13019524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak            this.digits = digits;
13029524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak            this.nDigits = nDigits;
13039524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak            this.isExceptional = false;
13049524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak            return this;
130551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } catch ( StringIndexOutOfBoundsException e ){ }
130651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        throw new NumberFormatException("For input string: \"" + in + "\"");
130751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
130851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
130951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /*
131051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Take a FloatingDecimal, which we presumably just scanned in,
131151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * and find out what its value is, as a double.
131251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
131351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * AS A SIDE EFFECT, SET roundDir TO INDICATE PREFERRED
131451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * ROUNDING DIRECTION in case the result is really destined
131551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * for a single-precision float.
131651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
131751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
131851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public strictfp double doubleValue(){
131951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int     kDigits = Math.min( nDigits, maxDecimalDigits+1 );
132051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        long    lValue;
132151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        double  dValue;
132251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        double  rValue, tValue;
132351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
132451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // First, check for NaN and Infinity values
132551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if(digits == infinity || digits == notANumber) {
132651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if(digits == notANumber)
132751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return Double.NaN;
132851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            else
132951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return (isNegative?Double.NEGATIVE_INFINITY:Double.POSITIVE_INFINITY);
133051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
133151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        else {
133251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (mustSetRoundDir) {
133351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                roundDir = 0;
133451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
133551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            /*
133651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * convert the lead kDigits to a long integer.
133751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             */
133851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // (special performance hack: start to do it using int)
133951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            int iValue = (int)digits[0]-(int)'0';
134051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            int iDigits = Math.min( kDigits, intDecimalDigits );
134151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            for ( int i=1; i < iDigits; i++ ){
134251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                iValue = iValue*10 + (int)digits[i]-(int)'0';
134351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
134451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            lValue = (long)iValue;
134551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            for ( int i=iDigits; i < kDigits; i++ ){
134651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                lValue = lValue*10L + (long)((int)digits[i]-(int)'0');
134751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
134851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            dValue = (double)lValue;
134951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            int exp = decExponent-kDigits;
135051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            /*
135151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * lValue now contains a long integer with the value of
135251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * the first kDigits digits of the number.
135351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * dValue contains the (double) of the same.
135451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             */
135551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
135651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ( nDigits <= maxDecimalDigits ){
135751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                /*
135851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * possibly an easy case.
135951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * We know that the digits can be represented
136051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * exactly. And if the exponent isn't too outrageous,
136151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * the whole thing can be done with one operation,
136251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * thus one rounding error.
136351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * Note that all our constructors trim all leading and
136451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * trailing zeros, so simple values (including zero)
136551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * will always end up here
136651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 */
136751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (exp == 0 || dValue == 0.0)
136851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    return (isNegative)? -dValue : dValue; // small floating integer
136951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                else if ( exp >= 0 ){
137051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ( exp <= maxSmallTen ){
137151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        /*
137251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * Can get the answer with one operation,
137351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * thus one roundoff.
137451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         */
137551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        rValue = dValue * small10pow[exp];
137651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        if ( mustSetRoundDir ){
137751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            tValue = rValue / small10pow[exp];
137851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            roundDir = ( tValue ==  dValue ) ? 0
137951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                :( tValue < dValue ) ? 1
138051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                : -1;
138151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
138251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        return (isNegative)? -rValue : rValue;
138351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
138451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    int slop = maxDecimalDigits - kDigits;
138551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ( exp <= maxSmallTen+slop ){
138651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        /*
138751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * We can multiply dValue by 10^(slop)
138851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * and it is still "small" and exact.
138951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * Then we can multiply by 10^(exp-slop)
139051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * with one rounding.
139151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         */
139251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        dValue *= small10pow[slop];
139351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        rValue = dValue * small10pow[exp-slop];
139451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
139551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        if ( mustSetRoundDir ){
139651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            tValue = rValue / small10pow[exp-slop];
139751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            roundDir = ( tValue ==  dValue ) ? 0
139851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                :( tValue < dValue ) ? 1
139951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                : -1;
140051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
140151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        return (isNegative)? -rValue : rValue;
140251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
140351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    /*
140451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     * Else we have a hard case with a positive exp.
140551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     */
140651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else {
140751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ( exp >= -maxSmallTen ){
140851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        /*
140951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * Can get the answer in one division.
141051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         */
141151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        rValue = dValue / small10pow[-exp];
141251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        tValue = rValue * small10pow[-exp];
141351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        if ( mustSetRoundDir ){
141451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            roundDir = ( tValue ==  dValue ) ? 0
141551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                :( tValue < dValue ) ? 1
141651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                : -1;
141751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
141851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        return (isNegative)? -rValue : rValue;
141951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
142051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    /*
142151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     * Else we have a hard case with a negative exp.
142251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     */
142351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
142451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
142551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
142651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            /*
142751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * Harder cases:
142851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * The sum of digits plus exponent is greater than
142951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * what we think we can do with one error.
143051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             *
143151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * Start by approximating the right answer by,
143251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * naively, scaling by powers of 10.
143351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             */
143451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ( exp > 0 ){
143551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if ( decExponent > maxDecimalExponent+1 ){
143651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    /*
143751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     * Lets face it. This is going to be
143851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     * Infinity. Cut to the chase.
143951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     */
144051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    return (isNegative)? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
144151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
144251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if ( (exp&15) != 0 ){
144351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    dValue *= small10pow[exp&15];
144451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
144551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if ( (exp>>=4) != 0 ){
144651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    int j;
144751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    for( j = 0; exp > 1; j++, exp>>=1 ){
144851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        if ( (exp&1)!=0)
144951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            dValue *= big10pow[j];
145051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
145151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    /*
145251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     * The reason for the weird exp > 1 condition
145351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     * in the above loop was so that the last multiply
145451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     * would get unrolled. We handle it here.
145551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     * It could overflow.
145651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     */
145751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    double t = dValue * big10pow[j];
145851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ( Double.isInfinite( t ) ){
145951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        /*
146051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * It did overflow.
146151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * Look more closely at the result.
146251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * If the exponent is just one too large,
146351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * then use the maximum finite as our estimate
146451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * value. Else call the result infinity
146551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * and punt it.
146651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * ( I presume this could happen because
146751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * rounding forces the result here to be
146851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * an ULP or two larger than
146951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * Double.MAX_VALUE ).
147051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         */
147151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        t = dValue / 2.0;
147251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        t *= big10pow[j];
147351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        if ( Double.isInfinite( t ) ){
147451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            return (isNegative)? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
147551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
147651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        t = Double.MAX_VALUE;
147751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
147851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    dValue = t;
147951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
148051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else if ( exp < 0 ){
148151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                exp = -exp;
148251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if ( decExponent < minDecimalExponent-1 ){
148351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    /*
148451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     * Lets face it. This is going to be
148551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     * zero. Cut to the chase.
148651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     */
148751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    return (isNegative)? -0.0 : 0.0;
148851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
148951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if ( (exp&15) != 0 ){
149051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    dValue /= small10pow[exp&15];
149151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
149251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if ( (exp>>=4) != 0 ){
149351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    int j;
149451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    for( j = 0; exp > 1; j++, exp>>=1 ){
149551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        if ( (exp&1)!=0)
149651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            dValue *= tiny10pow[j];
149751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
149851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    /*
149951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     * The reason for the weird exp > 1 condition
150051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     * in the above loop was so that the last multiply
150151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     * would get unrolled. We handle it here.
150251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     * It could underflow.
150351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     */
150451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    double t = dValue * tiny10pow[j];
150551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ( t == 0.0 ){
150651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        /*
150751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * It did underflow.
150851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * Look more closely at the result.
150951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * If the exponent is just one too small,
151051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * then use the minimum finite as our estimate
151151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * value. Else call the result 0.0
151251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * and punt it.
151351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * ( I presume this could happen because
151451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * rounding forces the result here to be
151551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * an ULP or two less than
151651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * Double.MIN_VALUE ).
151751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         */
151851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        t = dValue * 2.0;
151951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        t *= tiny10pow[j];
152051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        if ( t == 0.0 ){
152151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            return (isNegative)? -0.0 : 0.0;
152251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
152351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        t = Double.MIN_VALUE;
152451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
152551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    dValue = t;
152651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
152751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
152851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
152951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            /*
153051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * dValue is now approximately the result.
153151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * The hard part is adjusting it, by comparison
153251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * with FDBigInt arithmetic.
153351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * Formulate the EXACT big-number result as
153451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * bigD0 * 10^exp
153551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             */
153651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            FDBigInt bigD0 = new FDBigInt( lValue, digits, kDigits, nDigits );
153751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            exp   = decExponent - nDigits;
153851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
153951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            correctionLoop:
154051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            while(true){
154151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                /* AS A SIDE EFFECT, THIS METHOD WILL SET THE INSTANCE VARIABLES
154251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * bigIntExp and bigIntNBits
154351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 */
154451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                FDBigInt bigB = doubleToBigInt( dValue );
154551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
154651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                /*
154751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * Scale bigD, bigB appropriately for
154851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * big-integer operations.
154951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * Naively, we multiply by powers of ten
155051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * and powers of two. What we actually do
155151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * is keep track of the powers of 5 and
155251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * powers of 2 we would use, then factor out
155351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * common divisors before doing the work.
155451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 */
155551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                int B2, B5; // powers of 2, 5 in bigB
155651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                int     D2, D5; // powers of 2, 5 in bigD
155751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                int Ulp2;   // powers of 2 in halfUlp.
155851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if ( exp >= 0 ){
155951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    B2 = B5 = 0;
156051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    D2 = D5 = exp;
156151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else {
156251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    B2 = B5 = -exp;
156351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    D2 = D5 = 0;
156451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
156551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if ( bigIntExp >= 0 ){
156651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    B2 += bigIntExp;
156751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else {
156851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    D2 -= bigIntExp;
156951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
157051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                Ulp2 = B2;
157151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // shift bigB and bigD left by a number s. t.
157251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // halfUlp is still an integer.
157351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                int hulpbias;
157451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if ( bigIntExp+bigIntNBits <= -expBias+1 ){
157551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // This is going to be a denormalized number
157651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // (if not actually zero).
157751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // half an ULP is at 2^-(expBias+expShift+1)
157851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    hulpbias = bigIntExp+ expBias + expShift;
157951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else {
158051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    hulpbias = expShift + 2 - bigIntNBits;
158151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
158251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                B2 += hulpbias;
158351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                D2 += hulpbias;
158451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // if there are common factors of 2, we might just as well
158551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // factor them out, as they add nothing useful.
158651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                int common2 = Math.min( B2, Math.min( D2, Ulp2 ) );
158751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                B2 -= common2;
158851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                D2 -= common2;
158951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                Ulp2 -= common2;
159051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // do multiplications by powers of 5 and 2
159151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                bigB = multPow52( bigB, B5, B2 );
159251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                FDBigInt bigD = multPow52( new FDBigInt( bigD0 ), D5, D2 );
159351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                //
159451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // to recap:
159551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // bigB is the scaled-big-int version of our floating-point
159651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // candidate.
159751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // bigD is the scaled-big-int version of the exact value
159851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // as we understand it.
159951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // halfUlp is 1/2 an ulp of bigB, except for special cases
160051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // of exact powers of 2
160151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                //
160251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // the plan is to compare bigB with bigD, and if the difference
160351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // is less than halfUlp, then we're satisfied. Otherwise,
160451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // use the ratio of difference to halfUlp to calculate a fudge
160551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // factor to add to the floating value, then go 'round again.
160651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                //
160751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                FDBigInt diff;
160851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                int cmpResult;
160951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                boolean overvalue;
161051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if ( (cmpResult = bigB.cmp( bigD ) ) > 0 ){
161151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    overvalue = true; // our candidate is too big.
161251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    diff = bigB.sub( bigD );
161351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ( (bigIntNBits == 1) && (bigIntExp > -expBias+1) ){
161451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // candidate is a normalized exact power of 2 and
161551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // is too big. We will be subtracting.
161651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // For our purposes, ulp is the ulp of the
161751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // next smaller range.
161851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        Ulp2 -= 1;
161951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        if ( Ulp2 < 0 ){
162051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            // rats. Cannot de-scale ulp this far.
162151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            // must scale diff in other direction.
162251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            Ulp2 = 0;
162351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            diff.lshiftMe( 1 );
162451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
162551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
162651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else if ( cmpResult < 0 ){
162751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    overvalue = false; // our candidate is too small.
162851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    diff = bigD.sub( bigB );
162951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else {
163051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // the candidate is exactly right!
163151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // this happens with surprising frequency
163251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    break correctionLoop;
163351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
163451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                FDBigInt halfUlp = constructPow52( B5, Ulp2 );
163551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if ( (cmpResult = diff.cmp( halfUlp ) ) < 0 ){
163651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // difference is small.
163751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // this is close enough
163851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (mustSetRoundDir) {
163951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        roundDir = overvalue ? -1 : 1;
164051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
164151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    break correctionLoop;
164251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else if ( cmpResult == 0 ){
164351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // difference is exactly half an ULP
164451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // round to some other value maybe, then finish
164551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    dValue += 0.5*ulp( dValue, overvalue );
164651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // should check for bigIntNBits == 1 here??
164751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (mustSetRoundDir) {
164851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        roundDir = overvalue ? -1 : 1;
164951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
165051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    break correctionLoop;
165151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else {
165251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // difference is non-trivial.
165351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // could scale addend by ratio of difference to
165451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // halfUlp here, if we bothered to compute that difference.
165551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // Most of the time ( I hope ) it is about 1 anyway.
165651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    dValue += ulp( dValue, overvalue );
165751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ( dValue == 0.0 || dValue == Double.POSITIVE_INFINITY )
165851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        break correctionLoop; // oops. Fell off end of range.
165951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    continue; // try again.
166051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
166151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
166251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
166351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return (isNegative)? -dValue : dValue;
166451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
166551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
166651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
166751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /*
166851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Take a FloatingDecimal, which we presumably just scanned in,
166951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * and find out what its value is, as a float.
167051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * This is distinct from doubleValue() to avoid the extremely
167151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * unlikely case of a double rounding error, wherein the conversion
167251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * to double has one rounding error, and the conversion of that double
167351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * to a float has another rounding error, IN THE WRONG DIRECTION,
167451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * ( because of the preference to a zero low-order bit ).
167551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
167651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
167751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public strictfp float floatValue(){
167851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int     kDigits = Math.min( nDigits, singleMaxDecimalDigits+1 );
167951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int     iValue;
168051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        float   fValue;
168151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
168251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // First, check for NaN and Infinity values
168351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if(digits == infinity || digits == notANumber) {
168451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if(digits == notANumber)
168551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return Float.NaN;
168651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            else
168751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return (isNegative?Float.NEGATIVE_INFINITY:Float.POSITIVE_INFINITY);
168851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
168951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        else {
169051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            /*
169151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * convert the lead kDigits to an integer.
169251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             */
169351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            iValue = (int)digits[0]-(int)'0';
169451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            for ( int i=1; i < kDigits; i++ ){
169551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                iValue = iValue*10 + (int)digits[i]-(int)'0';
169651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
169751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            fValue = (float)iValue;
169851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            int exp = decExponent-kDigits;
169951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            /*
170051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * iValue now contains an integer with the value of
170151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * the first kDigits digits of the number.
170251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * fValue contains the (float) of the same.
170351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             */
170451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
170551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ( nDigits <= singleMaxDecimalDigits ){
170651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                /*
170751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * possibly an easy case.
170851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * We know that the digits can be represented
170951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * exactly. And if the exponent isn't too outrageous,
171051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * the whole thing can be done with one operation,
171151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * thus one rounding error.
171251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * Note that all our constructors trim all leading and
171351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * trailing zeros, so simple values (including zero)
171451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * will always end up here.
171551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 */
171651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (exp == 0 || fValue == 0.0f)
171751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    return (isNegative)? -fValue : fValue; // small floating integer
171851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                else if ( exp >= 0 ){
171951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ( exp <= singleMaxSmallTen ){
172051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        /*
172151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * Can get the answer with one operation,
172251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * thus one roundoff.
172351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         */
172451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        fValue *= singleSmall10pow[exp];
172551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        return (isNegative)? -fValue : fValue;
172651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
172751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    int slop = singleMaxDecimalDigits - kDigits;
172851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ( exp <= singleMaxSmallTen+slop ){
172951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        /*
173051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * We can multiply dValue by 10^(slop)
173151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * and it is still "small" and exact.
173251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * Then we can multiply by 10^(exp-slop)
173351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * with one rounding.
173451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         */
173551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        fValue *= singleSmall10pow[slop];
173651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        fValue *= singleSmall10pow[exp-slop];
173751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        return (isNegative)? -fValue : fValue;
173851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
173951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    /*
174051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     * Else we have a hard case with a positive exp.
174151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     */
174251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else {
174351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ( exp >= -singleMaxSmallTen ){
174451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        /*
174551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * Can get the answer in one division.
174651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         */
174751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        fValue /= singleSmall10pow[-exp];
174851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        return (isNegative)? -fValue : fValue;
174951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
175051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    /*
175151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     * Else we have a hard case with a negative exp.
175251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     */
175351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
175451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else if ( (decExponent >= nDigits) && (nDigits+decExponent <= maxDecimalDigits) ){
175551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                /*
175651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * In double-precision, this is an exact floating integer.
175751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * So we can compute to double, then shorten to float
175851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * with one round, and get the right answer.
175951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 *
176051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * First, finish accumulating digits.
176151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * Then convert that integer to a double, multiply
176251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * by the appropriate power of ten, and convert to float.
176351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 */
176451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                long lValue = (long)iValue;
176551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                for ( int i=kDigits; i < nDigits; i++ ){
176651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    lValue = lValue*10L + (long)((int)digits[i]-(int)'0');
176751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
176851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                double dValue = (double)lValue;
176951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                exp = decExponent-nDigits;
177051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                dValue *= small10pow[exp];
177151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                fValue = (float)dValue;
177251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return (isNegative)? -fValue : fValue;
177351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
177451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
177551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            /*
177651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * Harder cases:
177751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * The sum of digits plus exponent is greater than
177851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * what we think we can do with one error.
177951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             *
178051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * Start by weeding out obviously out-of-range
178151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * results, then convert to double and go to
178251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * common hard-case code.
178351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             */
178451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ( decExponent > singleMaxDecimalExponent+1 ){
178551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                /*
178651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * Lets face it. This is going to be
178751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * Infinity. Cut to the chase.
178851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 */
178951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return (isNegative)? Float.NEGATIVE_INFINITY : Float.POSITIVE_INFINITY;
179051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else if ( decExponent < singleMinDecimalExponent-1 ){
179151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                /*
179251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * Lets face it. This is going to be
179351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * zero. Cut to the chase.
179451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 */
179551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return (isNegative)? -0.0f : 0.0f;
179651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
179751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
179851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            /*
179951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * Here, we do 'way too much work, but throwing away
180051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * our partial results, and going and doing the whole
180151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * thing as double, then throwing away half the bits that computes
180251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * when we convert back to float.
180351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             *
180451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * The alternative is to reproduce the whole multiple-precision
180551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * algorithm for float precision, or to try to parameterize it
180651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * for common usage. The former will take about 400 lines of code,
180751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * and the latter I tried without success. Thus the semi-hack
180851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * answer here.
180951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             */
181051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            mustSetRoundDir = !fromHex;
181151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            double dValue = doubleValue();
181251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return stickyRound( dValue );
181351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
181451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
181551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
181651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
181751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /*
181851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * All the positive powers of 10 that can be
181951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * represented exactly in double/float.
182051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
182151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static final double small10pow[] = {
182251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        1.0e0,
182351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        1.0e1, 1.0e2, 1.0e3, 1.0e4, 1.0e5,
182451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        1.0e6, 1.0e7, 1.0e8, 1.0e9, 1.0e10,
182551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        1.0e11, 1.0e12, 1.0e13, 1.0e14, 1.0e15,
182651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        1.0e16, 1.0e17, 1.0e18, 1.0e19, 1.0e20,
182751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        1.0e21, 1.0e22
182851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    };
182951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
183051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static final float singleSmall10pow[] = {
183151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        1.0e0f,
183251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        1.0e1f, 1.0e2f, 1.0e3f, 1.0e4f, 1.0e5f,
183351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        1.0e6f, 1.0e7f, 1.0e8f, 1.0e9f, 1.0e10f
183451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    };
183551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
183651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static final double big10pow[] = {
183751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        1e16, 1e32, 1e64, 1e128, 1e256 };
183851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static final double tiny10pow[] = {
183951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        1e-16, 1e-32, 1e-64, 1e-128, 1e-256 };
184051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
184151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static final int maxSmallTen = small10pow.length-1;
184251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static final int singleMaxSmallTen = singleSmall10pow.length-1;
184351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
184451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static final int small5pow[] = {
184551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        1,
184651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5,
184751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5*5,
184851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5*5*5,
184951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5*5*5*5,
185051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5*5*5*5*5,
185151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5*5*5*5*5*5,
185251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5*5*5*5*5*5*5,
185351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5*5*5*5*5*5*5*5,
185451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5*5*5*5*5*5*5*5*5,
185551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5*5*5*5*5*5*5*5*5*5,
185651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5*5*5*5*5*5*5*5*5*5*5,
185751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5*5*5*5*5*5*5*5*5*5*5*5,
185851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5*5*5*5*5*5*5*5*5*5*5*5*5
185951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    };
186051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
186151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
186251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static final long long5pow[] = {
186351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        1L,
186451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L,
186551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5,
186651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5,
186751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5*5,
186851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5*5*5,
186951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5*5*5*5,
187051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5*5*5*5*5,
187151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5*5*5*5*5*5,
187251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5*5*5*5*5*5*5,
187351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5*5*5*5*5*5*5*5,
187451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5*5*5*5*5*5*5*5*5,
187551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5*5*5*5*5*5*5*5*5*5,
187651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5*5*5*5*5*5*5*5*5*5*5,
187751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5*5*5*5*5*5*5*5*5*5*5*5,
187851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
187951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
188051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
188151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
188251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
188351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
188451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
188551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
188651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
188751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr 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,
188851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr 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,
188951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr 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,
189051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    };
189151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
189251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // approximately ceil( log2( long5pow[i] ) )
189351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static final int n5bits[] = {
189451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        0,
189551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        3,
189651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        5,
189751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        7,
189851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        10,
189951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        12,
190051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        14,
190151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        17,
190251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        19,
190351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        21,
190451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        24,
190551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        26,
190651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        28,
190751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        31,
190851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        33,
190951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        35,
191051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        38,
191151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        40,
191251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        42,
191351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        45,
191451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        47,
191551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        49,
191651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        52,
191751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        54,
191851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        56,
191951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        59,
192051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        61,
192151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    };
192251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
192351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static final char infinity[] = { 'I', 'n', 'f', 'i', 'n', 'i', 't', 'y' };
192451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static final char notANumber[] = { 'N', 'a', 'N' };
192551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static final char zero[] = { '0', '0', '0', '0', '0', '0', '0', '0' };
192651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
192751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
192851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /*
192951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Grammar is compatible with hexadecimal floating-point constants
193051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * described in section 6.4.4.2 of the C99 specification.
193151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
193251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static Pattern hexFloatPattern = null;
193351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static synchronized Pattern getHexFloatPattern() {
193451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (hexFloatPattern == null) {
193551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski           hexFloatPattern = Pattern.compile(
193651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                   //1           234                   56                7                   8      9
193751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    "([-+])?0[xX](((\\p{XDigit}+)\\.?)|((\\p{XDigit}*)\\.(\\p{XDigit}+)))[pP]([-+])?(\\p{Digit}+)[fFdD]?"
193851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    );
193951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
194051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return hexFloatPattern;
194151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
194251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
194351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /*
194451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Convert string s to a suitable floating decimal; uses the
194551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * double constructor and set the roundDir variable appropriately
194651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * in case the value is later converted to a float.
194751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
19489524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak    FloatingDecimal parseHexString(String s) {
194951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Verify string is a member of the hexadecimal floating-point
195051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // string language.
195151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        Matcher m = getHexFloatPattern().matcher(s);
195251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        boolean validInput = m.matches();
195351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
195451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (!validInput) {
195551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // Input does not match pattern
195651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new NumberFormatException("For input string: \"" + s + "\"");
195751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else { // validInput
195851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            /*
195951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * We must isolate the sign, significand, and exponent
196051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * fields.  The sign value is straightforward.  Since
196151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * floating-point numbers are stored with a normalized
196251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * representation, the significand and exponent are
196351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * interrelated.
196451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             *
196551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * After extracting the sign, we normalized the
196651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * significand as a hexadecimal value, calculating an
196751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * exponent adjust for any shifts made during
196851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * normalization.  If the significand is zero, the
196951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * exponent doesn't need to be examined since the output
197051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * will be zero.
197151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             *
197251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * Next the exponent in the input string is extracted.
197351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * Afterwards, the significand is normalized as a *binary*
197451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * value and the input value's normalized exponent can be
197551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * computed.  The significand bits are copied into a
197651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * double significand; if the string has more logical bits
197751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * than can fit in a double, the extra bits affect the
197851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * round and sticky bits which are used to round the final
197951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * value.
198051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             */
198151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
198251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            //  Extract significand sign
198351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            String group1 = m.group(1);
198451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            double sign = (( group1 == null ) || group1.equals("+"))? 1.0 : -1.0;
198551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
198651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
198751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            //  Extract Significand magnitude
198851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            /*
198951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * Based on the form of the significand, calculate how the
199051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * binary exponent needs to be adjusted to create a
199151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * normalized *hexadecimal* floating-point number; that
199251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * is, a number where there is one nonzero hex digit to
199351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * the left of the (hexa)decimal point.  Since we are
199451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * adjusting a binary, not hexadecimal exponent, the
199551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * exponent is adjusted by a multiple of 4.
199651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             *
199751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * There are a number of significand scenarios to consider;
199851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * letters are used in indicate nonzero digits:
199951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             *
200051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * 1. 000xxxx       =>      x.xxx   normalized
200151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             *    increase exponent by (number of x's - 1)*4
200251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             *
200351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * 2. 000xxx.yyyy =>        x.xxyyyy        normalized
200451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             *    increase exponent by (number of x's - 1)*4
200551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             *
200651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * 3. .000yyy  =>   y.yy    normalized
200751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             *    decrease exponent by (number of zeros + 1)*4
200851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             *
200951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * 4. 000.00000yyy => y.yy normalized
201051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             *    decrease exponent by (number of zeros to right of point + 1)*4
201151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             *
201251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * If the significand is exactly zero, return a properly
201351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * signed zero.
201451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             */
201551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
201651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            String significandString =null;
201751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            int signifLength = 0;
201851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            int exponentAdjust = 0;
201951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            {
202051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                int leftDigits  = 0; // number of meaningful digits to
202151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                     // left of "decimal" point
202251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                     // (leading zeros stripped)
202351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                int rightDigits = 0; // number of digits to right of
202451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                     // "decimal" point; leading zeros
202551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                     // must always be accounted for
202651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                /*
202751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * The significand is made up of either
202851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 *
202951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * 1. group 4 entirely (integer portion only)
203051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 *
203151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * OR
203251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 *
203351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * 2. the fractional portion from group 7 plus any
203451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * (optional) integer portions from group 6.
203551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 */
203651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                String group4;
203751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if( (group4 = m.group(4)) != null) {  // Integer-only significand
203851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // Leading zeros never matter on the integer portion
203951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    significandString = stripLeadingZeros(group4);
204051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    leftDigits = significandString.length();
204151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
204251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                else {
204351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // Group 6 is the optional integer; leading zeros
204451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // never matter on the integer portion
204551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    String group6 = stripLeadingZeros(m.group(6));
204651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    leftDigits = group6.length();
204751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
204851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // fraction
204951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    String group7 = m.group(7);
205051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    rightDigits = group7.length();
205151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
205251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // Turn "integer.fraction" into "integer"+"fraction"
205351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    significandString =
205451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        ((group6 == null)?"":group6) + // is the null
205551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // check necessary?
205651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        group7;
205751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
205851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
205951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                significandString = stripLeadingZeros(significandString);
206051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                signifLength  = significandString.length();
206151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
206251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                /*
206351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * Adjust exponent as described above
206451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 */
206551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (leftDigits >= 1) {  // Cases 1 and 2
206651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    exponentAdjust = 4*(leftDigits - 1);
206751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else {                // Cases 3 and 4
206851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    exponentAdjust = -4*( rightDigits - signifLength + 1);
206951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
207051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
207151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // If the significand is zero, the exponent doesn't
207251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // matter; return a properly signed zero.
207351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
207451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (signifLength == 0) { // Only zeros in input
20759524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak                    return loadDouble(sign * 0.0);
207651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
207751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
207851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
207951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            //  Extract Exponent
208051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            /*
208151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * Use an int to read in the exponent value; this should
208251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * provide more than sufficient range for non-contrived
208351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * inputs.  If reading the exponent in as an int does
208451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * overflow, examine the sign of the exponent and
208551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * significand to determine what to do.
208651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             */
208751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            String group8 = m.group(8);
208851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            boolean positiveExponent = ( group8 == null ) || group8.equals("+");
208951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            long unsignedRawExponent;
209051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            try {
209151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                unsignedRawExponent = Integer.parseInt(m.group(9));
209251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
209351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            catch (NumberFormatException e) {
209451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // At this point, we know the exponent is
209551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // syntactically well-formed as a sequence of
209651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // digits.  Therefore, if an NumberFormatException
209751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // is thrown, it must be due to overflowing int's
209851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // range.  Also, at this point, we have already
209951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // checked for a zero significand.  Thus the signs
210051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // of the exponent and significand determine the
210151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // final result:
210251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                //
210351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                //                      significand
210451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                //                      +               -
210551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // exponent     +       +infinity       -infinity
210651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                //              -       +0.0            -0.0
21079524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak                return loadDouble(sign * (positiveExponent ?
21089524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak                                          Double.POSITIVE_INFINITY : 0.0));
210951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
211051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
211151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            long rawExponent =
211251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                (positiveExponent ? 1L : -1L) * // exponent sign
211351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                unsignedRawExponent;            // exponent magnitude
211451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
211551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // Calculate partially adjusted exponent
211651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            long exponent = rawExponent + exponentAdjust ;
211751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
211851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // Starting copying non-zero bits into proper position in
211951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // a long; copy explicit bit too; this will be masked
212051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // later for normal values.
212151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
212251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            boolean round = false;
212351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            boolean sticky = false;
212451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            int bitsCopied=0;
212551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            int nextShift=0;
212651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            long significand=0L;
212751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // First iteration is different, since we only copy
212851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // from the leading significand bit; one more exponent
212951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // adjust will be needed...
213051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
213151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // IMPORTANT: make leadingDigit a long to avoid
213251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // surprising shift semantics!
213351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            long leadingDigit = getHexDigit(significandString, 0);
213451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
213551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            /*
213651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * Left shift the leading digit (53 - (bit position of
213751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * leading 1 in digit)); this sets the top bit of the
213851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * significand to 1.  The nextShift value is adjusted
213951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * to take into account the number of bit positions of
214051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * the leadingDigit actually used.  Finally, the
214151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * exponent is adjusted to normalize the significand
214251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * as a binary value, not just a hex value.
214351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             */
214451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (leadingDigit == 1) {
214551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                significand |= leadingDigit << 52;
214651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                nextShift = 52 - 4;
214751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                /* exponent += 0 */     }
214851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            else if (leadingDigit <= 3) { // [2, 3]
214951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                significand |= leadingDigit << 51;
215051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                nextShift = 52 - 5;
215151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                exponent += 1;
215251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
215351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            else if (leadingDigit <= 7) { // [4, 7]
215451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                significand |= leadingDigit << 50;
215551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                nextShift = 52 - 6;
215651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                exponent += 2;
215751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
215851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            else if (leadingDigit <= 15) { // [8, f]
215951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                significand |= leadingDigit << 49;
216051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                nextShift = 52 - 7;
216151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                exponent += 3;
216251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else {
216351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                throw new AssertionError("Result from digit conversion too large!");
216451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
216551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // The preceding if-else could be replaced by a single
216651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // code block based on the high-order bit set in
216751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // leadingDigit.  Given leadingOnePosition,
216851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
216951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // significand |= leadingDigit << (SIGNIFICAND_WIDTH - leadingOnePosition);
217051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // nextShift = 52 - (3 + leadingOnePosition);
217151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // exponent += (leadingOnePosition-1);
217251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
217351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
217451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            /*
217551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * Now the exponent variable is equal to the normalized
217651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * binary exponent.  Code below will make representation
217751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * adjustments if the exponent is incremented after
217851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * rounding (includes overflows to infinity) or if the
217951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * result is subnormal.
218051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             */
218151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
218251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // Copy digit into significand until the significand can't
218351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // hold another full hex digit or there are no more input
218451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // hex digits.
218551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            int i = 0;
218651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            for(i = 1;
218751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                i < signifLength && nextShift >= 0;
218851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                i++) {
218951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                long currentDigit = getHexDigit(significandString, i);
219051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                significand |= (currentDigit << nextShift);
219151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                nextShift-=4;
219251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
219351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
219451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // After the above loop, the bulk of the string is copied.
219551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // Now, we must copy any partial hex digits into the
219651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // significand AND compute the round bit and start computing
219751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // sticky bit.
219851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
219951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ( i < signifLength ) { // at least one hex input digit exists
220051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                long currentDigit = getHexDigit(significandString, i);
220151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
220251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // from nextShift, figure out how many bits need
220351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // to be copied, if any
220451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                switch(nextShift) { // must be negative
220551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                case -1:
220651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // three bits need to be copied in; can
220751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // set round bit
220851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    significand |= ((currentDigit & 0xEL) >> 1);
220951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    round = (currentDigit & 0x1L)  != 0L;
221051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    break;
221151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
221251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                case -2:
221351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // two bits need to be copied in; can
221451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // set round and start sticky
221551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    significand |= ((currentDigit & 0xCL) >> 2);
221651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    round = (currentDigit &0x2L)  != 0L;
221751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    sticky = (currentDigit & 0x1L) != 0;
221851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    break;
221951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
222051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                case -3:
222151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // one bit needs to be copied in
222251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    significand |= ((currentDigit & 0x8L)>>3);
222351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // Now set round and start sticky, if possible
222451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    round = (currentDigit &0x4L)  != 0L;
222551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    sticky = (currentDigit & 0x3L) != 0;
222651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    break;
222751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
222851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                case -4:
222951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // all bits copied into significand; set
223051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // round and start sticky
223151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    round = ((currentDigit & 0x8L) != 0);  // is top bit set?
223251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // nonzeros in three low order bits?
223351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    sticky = (currentDigit & 0x7L) != 0;
223451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    break;
223551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
223651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                default:
223751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    throw new AssertionError("Unexpected shift distance remainder.");
223851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // break;
223951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
224051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
224151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // Round is set; sticky might be set.
224251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
224351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // For the sticky bit, it suffices to check the
224451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // current digit and test for any nonzero digits in
224551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // the remaining unprocessed input.
224651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                i++;
224751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                while(i < signifLength && !sticky) {
224851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    currentDigit =  getHexDigit(significandString,i);
224951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    sticky = sticky || (currentDigit != 0);
225051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    i++;
225151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
225251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
225351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
225451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // else all of string was seen, round and sticky are
225551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // correct as false.
225651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
225751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
225851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // Check for overflow and update exponent accordingly.
225951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
226051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (exponent > DoubleConsts.MAX_EXPONENT) {         // Infinite result
226151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // overflow to properly signed infinity
22629524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak                return loadDouble(sign * Double.POSITIVE_INFINITY);
226351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else {  // Finite return value
226451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (exponent <= DoubleConsts.MAX_EXPONENT && // (Usually) normal result
226551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    exponent >= DoubleConsts.MIN_EXPONENT) {
226651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
226751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // The result returned in this block cannot be a
226851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // zero or subnormal; however after the
226951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // significand is adjusted from rounding, we could
227051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // still overflow in infinity.
227151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
227251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // AND exponent bits into significand; if the
227351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // significand is incremented and overflows from
227451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // rounding, this combination will update the
227551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // exponent correctly, even in the case of
227651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // Double.MAX_VALUE overflowing to infinity.
227751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
227851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    significand = (( ((long)exponent +
227951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                     (long)DoubleConsts.EXP_BIAS) <<
228051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                     (DoubleConsts.SIGNIFICAND_WIDTH-1))
228151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                   & DoubleConsts.EXP_BIT_MASK) |
228251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        (DoubleConsts.SIGNIF_BIT_MASK & significand);
228351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
228451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }  else  {  // Subnormal or zero
228551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // (exponent < DoubleConsts.MIN_EXPONENT)
228651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
228751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (exponent < (DoubleConsts.MIN_SUB_EXPONENT -1 )) {
228851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // No way to round back to nonzero value
228951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // regardless of significand if the exponent is
229051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // less than -1075.
22919524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak                        return loadDouble(sign * 0.0);
229251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    } else { //  -1075 <= exponent <= MIN_EXPONENT -1 = -1023
229351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        /*
229451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * Find bit position to round to; recompute
229551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * round and sticky bits, and shift
229651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * significand right appropriately.
229751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         */
229851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
229951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        sticky = sticky || round;
230051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        round = false;
230151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
230251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // Number of bits of significand to preserve is
230351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // exponent - abs_min_exp +1
230451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // check:
230551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // -1075 +1074 + 1 = 0
230651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // -1023 +1074 + 1 = 52
230751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
230851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        int bitsDiscarded = 53 -
230951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            ((int)exponent - DoubleConsts.MIN_SUB_EXPONENT + 1);
231051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        assert bitsDiscarded >= 1 && bitsDiscarded <= 53;
231151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
231251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // What to do here:
231351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // First, isolate the new round bit
231451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        round = (significand & (1L << (bitsDiscarded -1))) != 0L;
231551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        if (bitsDiscarded > 1) {
231651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            // create mask to update sticky bits; low
231751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            // order bitsDiscarded bits should be 1
231851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            long mask = ~((~0L) << (bitsDiscarded -1));
231951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            sticky = sticky || ((significand & mask) != 0L ) ;
232051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
232151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
232251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // Now, discard the bits
232351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        significand = significand >> bitsDiscarded;
232451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
232551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        significand = (( ((long)(DoubleConsts.MIN_EXPONENT -1) + // subnorm exp.
232651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                          (long)DoubleConsts.EXP_BIAS) <<
232751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                         (DoubleConsts.SIGNIFICAND_WIDTH-1))
232851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                       & DoubleConsts.EXP_BIT_MASK) |
232951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            (DoubleConsts.SIGNIF_BIT_MASK & significand);
233051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
233151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
233251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
233351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // The significand variable now contains the currently
233451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // appropriate exponent bits too.
233551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
233651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                /*
233751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * Determine if significand should be incremented;
233851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * making this determination depends on the least
233951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * significant bit and the round and sticky bits.
234051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 *
234151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * Round to nearest even rounding table, adapted from
234251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * table 4.7 in "Computer Arithmetic" by IsraelKoren.
234351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * The digit to the left of the "decimal" point is the
234451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * least significant bit, the digits to the right of
234551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * the point are the round and sticky bits
234651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 *
234751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * Number       Round(x)
234851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * x0.00        x0.
234951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * x0.01        x0.
235051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * x0.10        x0.
235151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * x0.11        x1. = x0. +1
235251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * x1.00        x1.
235351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * x1.01        x1.
235451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * x1.10        x1. + 1
235551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * x1.11        x1. + 1
235651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 */
235751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                boolean incremented = false;
235851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                boolean leastZero  = ((significand & 1L) == 0L);
235951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if( (  leastZero  && round && sticky ) ||
236051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    ((!leastZero) && round )) {
236151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    incremented = true;
236251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    significand++;
236351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
236451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
23659524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak                loadDouble(FpUtils.rawCopySign(
23669524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak                                               Double.longBitsToDouble(significand),
23679524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak                                               sign));
236851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
236951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                /*
237051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * Set roundingDir variable field of fd properly so
237151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * that the input string can be properly rounded to a
237251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * float value.  There are two cases to consider:
237351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 *
237451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * 1. rounding to double discards sticky bit
237551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * information that would change the result of a float
237651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * rounding (near halfway case between two floats)
237751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 *
237851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * 2. rounding to double rounds up when rounding up
237951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * would not occur when rounding to float.
238051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 *
238151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * For former case only needs to be considered when
238251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * the bits rounded away when casting to float are all
238351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * zero; otherwise, float round bit is properly set
238451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * and sticky will already be true.
238551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 *
238651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * The lower exponent bound for the code below is the
238751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * minimum (normalized) subnormal exponent - 1 since a
238851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * value with that exponent can round up to the
238951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * minimum subnormal value and the sticky bit
239051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * information must be preserved (i.e. case 1).
239151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 */
239251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if ((exponent >= FloatConsts.MIN_SUB_EXPONENT-1) &&
239351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    (exponent <= FloatConsts.MAX_EXPONENT ) ){
239451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // Outside above exponent range, the float value
239551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // will be zero or infinity.
239651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
239751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    /*
239851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     * If the low-order 28 bits of a rounded double
239951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     * significand are 0, the double could be a
240051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     * half-way case for a rounding to float.  If the
240151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     * double value is a half-way case, the double
240251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     * significand may have to be modified to round
240351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     * the the right float value (see the stickyRound
240451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     * method).  If the rounding to double has lost
240551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     * what would be float sticky bit information, the
240651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     * double significand must be incremented.  If the
240751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     * double value's significand was itself
240851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     * incremented, the float value may end up too
240951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     * large so the increment should be undone.
241051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     */
241151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ((significand & 0xfffffffL) ==  0x0L) {
241251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // For negative values, the sign of the
241351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // roundDir is the same as for positive values
241451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // since adding 1 increasing the significand's
241551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // magnitude and subtracting 1 decreases the
241651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // significand's magnitude.  If neither round
241751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // nor sticky is true, the double value is
241851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // exact and no adjustment is required for a
241951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // proper float rounding.
242051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        if( round || sticky) {
242151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            if (leastZero) { // prerounding lsb is 0
242251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                // If round and sticky were both true,
242351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                // and the least significant
242451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                // significand bit were 0, the rounded
242551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                // significand would not have its
242651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                // low-order bits be zero.  Therefore,
242751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                // we only need to adjust the
242851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                // significand if round XOR sticky is
242951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                // true.
243051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                if (round ^ sticky) {
24319524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak                                    this.roundDir =  1;
243251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                }
243351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            }
243451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            else { // prerounding lsb is 1
243551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                // If the prerounding lsb is 1 and the
243651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                // resulting significand has its
243751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                // low-order bits zero, the significand
243851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                // was incremented.  Here, we undo the
243951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                // increment, which will ensure the
244051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                // right guard and sticky bits for the
244151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                // float rounding.
244251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                if (round)
24439524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak                                    this.roundDir =  -1;
244451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            }
244551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
244651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
244751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
244851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
24499524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak                this.fromHex = true;
24509524178a7300a939242b78017f3dfa8014d4ca6dPrzemyslaw Szczepaniak                return this;
245151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
245251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
245351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
245451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
245551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
245651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Return <code>s</code> with any leading zeros removed.
245751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
245851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static String stripLeadingZeros(String s) {
245951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return  s.replaceFirst("^0+", "");
246051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
246151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
246251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
246351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Extract a hexadecimal digit from position <code>position</code>
246451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * of string <code>s</code>.
246551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
246651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static int getHexDigit(String s, int position) {
246751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int value = Character.digit(s.charAt(position), 16);
246851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (value <= -1 || value >= 16) {
246951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new AssertionError("Unexpected failure of digit conversion of " +
247051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                     s.charAt(position));
247151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
247251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return value;
247351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
247451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
247551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
247651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski}
2477