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