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