0N/A/*
3909N/A * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage sun.misc;
0N/A
0N/Aimport sun.misc.FpUtils;
0N/Aimport sun.misc.DoubleConsts;
0N/Aimport sun.misc.FloatConsts;
0N/Aimport java.util.regex.*;
0N/A
4124N/Apublic class FloatingDecimal{
0N/A boolean isExceptional;
0N/A boolean isNegative;
0N/A int decExponent;
0N/A char digits[];
0N/A int nDigits;
0N/A int bigIntExp;
0N/A int bigIntNBits;
0N/A boolean mustSetRoundDir = false;
0N/A boolean fromHex = false;
0N/A int roundDir = 0; // set by doubleValue
0N/A
0N/A private FloatingDecimal( boolean negSign, int decExponent, char []digits, int n, boolean e )
0N/A {
0N/A isNegative = negSign;
0N/A isExceptional = e;
0N/A this.decExponent = decExponent;
0N/A this.digits = digits;
0N/A this.nDigits = n;
0N/A }
0N/A
0N/A /*
0N/A * Constants of the implementation
0N/A * Most are IEEE-754 related.
0N/A * (There are more really boring constants at the end.)
0N/A */
0N/A static final long signMask = 0x8000000000000000L;
0N/A static final long expMask = 0x7ff0000000000000L;
0N/A static final long fractMask= ~(signMask|expMask);
0N/A static final int expShift = 52;
0N/A static final int expBias = 1023;
0N/A static final long fractHOB = ( 1L<<expShift ); // assumed High-Order bit
0N/A static final long expOne = ((long)expBias)<<expShift; // exponent of 1.0
0N/A static final int maxSmallBinExp = 62;
0N/A static final int minSmallBinExp = -( 63 / 3 );
0N/A static final int maxDecimalDigits = 15;
0N/A static final int maxDecimalExponent = 308;
0N/A static final int minDecimalExponent = -324;
0N/A static final int bigDecimalExponent = 324; // i.e. abs(minDecimalExponent)
0N/A
0N/A static final long highbyte = 0xff00000000000000L;
0N/A static final long highbit = 0x8000000000000000L;
0N/A static final long lowbytes = ~highbyte;
0N/A
0N/A static final int singleSignMask = 0x80000000;
0N/A static final int singleExpMask = 0x7f800000;
0N/A static final int singleFractMask = ~(singleSignMask|singleExpMask);
0N/A static final int singleExpShift = 23;
0N/A static final int singleFractHOB = 1<<singleExpShift;
0N/A static final int singleExpBias = 127;
0N/A static final int singleMaxDecimalDigits = 7;
0N/A static final int singleMaxDecimalExponent = 38;
0N/A static final int singleMinDecimalExponent = -45;
0N/A
0N/A static final int intDecimalDigits = 9;
0N/A
0N/A
0N/A /*
0N/A * count number of bits from high-order 1 bit to low-order 1 bit,
0N/A * inclusive.
0N/A */
0N/A private static int
0N/A countBits( long v ){
0N/A //
0N/A // the strategy is to shift until we get a non-zero sign bit
0N/A // then shift until we have no bits left, counting the difference.
0N/A // we do byte shifting as a hack. Hope it helps.
0N/A //
0N/A if ( v == 0L ) return 0;
0N/A
0N/A while ( ( v & highbyte ) == 0L ){
0N/A v <<= 8;
0N/A }
0N/A while ( v > 0L ) { // i.e. while ((v&highbit) == 0L )
0N/A v <<= 1;
0N/A }
0N/A
0N/A int n = 0;
0N/A while (( v & lowbytes ) != 0L ){
0N/A v <<= 8;
0N/A n += 8;
0N/A }
0N/A while ( v != 0L ){
0N/A v <<= 1;
0N/A n += 1;
0N/A }
0N/A return n;
0N/A }
0N/A
0N/A /*
0N/A * Keep big powers of 5 handy for future reference.
0N/A */
0N/A private static FDBigInt b5p[];
0N/A
0N/A private static synchronized FDBigInt
0N/A big5pow( int p ){
0N/A assert p >= 0 : p; // negative power of 5
0N/A if ( b5p == null ){
0N/A b5p = new FDBigInt[ p+1 ];
0N/A }else if (b5p.length <= p ){
0N/A FDBigInt t[] = new FDBigInt[ p+1 ];
0N/A System.arraycopy( b5p, 0, t, 0, b5p.length );
0N/A b5p = t;
0N/A }
0N/A if ( b5p[p] != null )
0N/A return b5p[p];
0N/A else if ( p < small5pow.length )
0N/A return b5p[p] = new FDBigInt( small5pow[p] );
0N/A else if ( p < long5pow.length )
0N/A return b5p[p] = new FDBigInt( long5pow[p] );
0N/A else {
0N/A // construct the value.
0N/A // recursively.
0N/A int q, r;
0N/A // in order to compute 5^p,
0N/A // compute its square root, 5^(p/2) and square.
0N/A // or, let q = p / 2, r = p -q, then
0N/A // 5^p = 5^(q+r) = 5^q * 5^r
0N/A q = p >> 1;
0N/A r = p - q;
0N/A FDBigInt bigq = b5p[q];
0N/A if ( bigq == null )
0N/A bigq = big5pow ( q );
0N/A if ( r < small5pow.length ){
0N/A return (b5p[p] = bigq.mult( small5pow[r] ) );
0N/A }else{
0N/A FDBigInt bigr = b5p[ r ];
0N/A if ( bigr == null )
0N/A bigr = big5pow( r );
0N/A return (b5p[p] = bigq.mult( bigr ) );
0N/A }
0N/A }
0N/A }
0N/A
0N/A //
0N/A // a common operation
0N/A //
0N/A private static FDBigInt
0N/A multPow52( FDBigInt v, int p5, int p2 ){
0N/A if ( p5 != 0 ){
0N/A if ( p5 < small5pow.length ){
0N/A v = v.mult( small5pow[p5] );
0N/A } else {
0N/A v = v.mult( big5pow( p5 ) );
0N/A }
0N/A }
0N/A if ( p2 != 0 ){
0N/A v.lshiftMe( p2 );
0N/A }
0N/A return v;
0N/A }
0N/A
0N/A //
0N/A // another common operation
0N/A //
0N/A private static FDBigInt
0N/A constructPow52( int p5, int p2 ){
0N/A FDBigInt v = new FDBigInt( big5pow( p5 ) );
0N/A if ( p2 != 0 ){
0N/A v.lshiftMe( p2 );
0N/A }
0N/A return v;
0N/A }
0N/A
0N/A /*
0N/A * Make a floating double into a FDBigInt.
0N/A * This could also be structured as a FDBigInt
0N/A * constructor, but we'd have to build a lot of knowledge
0N/A * about floating-point representation into it, and we don't want to.
0N/A *
0N/A * AS A SIDE EFFECT, THIS METHOD WILL SET THE INSTANCE VARIABLES
0N/A * bigIntExp and bigIntNBits
0N/A *
0N/A */
0N/A private FDBigInt
0N/A doubleToBigInt( double dval ){
0N/A long lbits = Double.doubleToLongBits( dval ) & ~signMask;
0N/A int binexp = (int)(lbits >>> expShift);
0N/A lbits &= fractMask;
0N/A if ( binexp > 0 ){
0N/A lbits |= fractHOB;
0N/A } else {
0N/A assert lbits != 0L : lbits; // doubleToBigInt(0.0)
0N/A binexp +=1;
0N/A while ( (lbits & fractHOB ) == 0L){
0N/A lbits <<= 1;
0N/A binexp -= 1;
0N/A }
0N/A }
0N/A binexp -= expBias;
0N/A int nbits = countBits( lbits );
0N/A /*
0N/A * We now know where the high-order 1 bit is,
0N/A * and we know how many there are.
0N/A */
0N/A int lowOrderZeros = expShift+1-nbits;
0N/A lbits >>>= lowOrderZeros;
0N/A
0N/A bigIntExp = binexp+1-nbits;
0N/A bigIntNBits = nbits;
0N/A return new FDBigInt( lbits );
0N/A }
0N/A
0N/A /*
0N/A * Compute a number that is the ULP of the given value,
0N/A * for purposes of addition/subtraction. Generally easy.
0N/A * More difficult if subtracting and the argument
0N/A * is a normalized a power of 2, as the ULP changes at these points.
0N/A */
4124N/A private static double ulp( double dval, boolean subtracting ){
0N/A long lbits = Double.doubleToLongBits( dval ) & ~signMask;
0N/A int binexp = (int)(lbits >>> expShift);
0N/A double ulpval;
0N/A if ( subtracting && ( binexp >= expShift ) && ((lbits&fractMask) == 0L) ){
0N/A // for subtraction from normalized, powers of 2,
0N/A // use next-smaller exponent
0N/A binexp -= 1;
0N/A }
0N/A if ( binexp > expShift ){
0N/A ulpval = Double.longBitsToDouble( ((long)(binexp-expShift))<<expShift );
0N/A } else if ( binexp == 0 ){
0N/A ulpval = Double.MIN_VALUE;
0N/A } else {
0N/A ulpval = Double.longBitsToDouble( 1L<<(binexp-1) );
0N/A }
0N/A if ( subtracting ) ulpval = - ulpval;
0N/A
0N/A return ulpval;
0N/A }
0N/A
0N/A /*
0N/A * Round a double to a float.
0N/A * In addition to the fraction bits of the double,
0N/A * look at the class instance variable roundDir,
0N/A * which should help us avoid double-rounding error.
0N/A * roundDir was set in hardValueOf if the estimate was
0N/A * close enough, but not exact. It tells us which direction
0N/A * of rounding is preferred.
0N/A */
0N/A float
0N/A stickyRound( double dval ){
0N/A long lbits = Double.doubleToLongBits( dval );
0N/A long binexp = lbits & expMask;
0N/A if ( binexp == 0L || binexp == expMask ){
0N/A // what we have here is special.
0N/A // don't worry, the right thing will happen.
0N/A return (float) dval;
0N/A }
0N/A lbits += (long)roundDir; // hack-o-matic.
0N/A return (float)Double.longBitsToDouble( lbits );
0N/A }
0N/A
0N/A
0N/A /*
0N/A * This is the easy subcase --
0N/A * all the significant bits, after scaling, are held in lvalue.
0N/A * negSign and decExponent tell us what processing and scaling
0N/A * has already been done. Exceptional cases have already been
0N/A * stripped out.
0N/A * In particular:
0N/A * lvalue is a finite number (not Inf, nor NaN)
0N/A * lvalue > 0L (not zero, nor negative).
0N/A *
0N/A * The only reason that we develop the digits here, rather than
0N/A * calling on Long.toString() is that we can do it a little faster,
0N/A * and besides want to treat trailing 0s specially. If Long.toString
0N/A * changes, we should re-evaluate this strategy!
0N/A */
0N/A private void
0N/A developLongDigits( int decExponent, long lvalue, long insignificant ){
0N/A char digits[];
0N/A int ndigits;
0N/A int digitno;
0N/A int c;
0N/A //
0N/A // Discard non-significant low-order bits, while rounding,
0N/A // up to insignificant value.
0N/A int i;
0N/A for ( i = 0; insignificant >= 10L; i++ )
0N/A insignificant /= 10L;
0N/A if ( i != 0 ){
0N/A long pow10 = long5pow[i] << i; // 10^i == 5^i * 2^i;
0N/A long residue = lvalue % pow10;
0N/A lvalue /= pow10;
0N/A decExponent += i;
0N/A if ( residue >= (pow10>>1) ){
0N/A // round up based on the low-order bits we're discarding
0N/A lvalue++;
0N/A }
0N/A }
0N/A if ( lvalue <= Integer.MAX_VALUE ){
0N/A assert lvalue > 0L : lvalue; // lvalue <= 0
0N/A // even easier subcase!
0N/A // can do int arithmetic rather than long!
0N/A int ivalue = (int)lvalue;
0N/A ndigits = 10;
0N/A digits = (char[])(perThreadBuffer.get());
0N/A digitno = ndigits-1;
0N/A c = ivalue%10;
0N/A ivalue /= 10;
0N/A while ( c == 0 ){
0N/A decExponent++;
0N/A c = ivalue%10;
0N/A ivalue /= 10;
0N/A }
0N/A while ( ivalue != 0){
0N/A digits[digitno--] = (char)(c+'0');
0N/A decExponent++;
0N/A c = ivalue%10;
0N/A ivalue /= 10;
0N/A }
0N/A digits[digitno] = (char)(c+'0');
0N/A } else {
0N/A // same algorithm as above (same bugs, too )
0N/A // but using long arithmetic.
0N/A ndigits = 20;
0N/A digits = (char[])(perThreadBuffer.get());
0N/A digitno = ndigits-1;
0N/A c = (int)(lvalue%10L);
0N/A lvalue /= 10L;
0N/A while ( c == 0 ){
0N/A decExponent++;
0N/A c = (int)(lvalue%10L);
0N/A lvalue /= 10L;
0N/A }
0N/A while ( lvalue != 0L ){
0N/A digits[digitno--] = (char)(c+'0');
0N/A decExponent++;
0N/A c = (int)(lvalue%10L);
0N/A lvalue /= 10;
0N/A }
0N/A digits[digitno] = (char)(c+'0');
0N/A }
0N/A char result [];
0N/A ndigits -= digitno;
0N/A result = new char[ ndigits ];
0N/A System.arraycopy( digits, digitno, result, 0, ndigits );
0N/A this.digits = result;
0N/A this.decExponent = decExponent+1;
0N/A this.nDigits = ndigits;
0N/A }
0N/A
0N/A //
0N/A // add one to the least significant digit.
0N/A // in the unlikely event there is a carry out,
0N/A // deal with it.
0N/A // assert that this will only happen where there
0N/A // is only one digit, e.g. (float)1e-44 seems to do it.
0N/A //
0N/A private void
0N/A roundup(){
0N/A int i;
0N/A int q = digits[ i = (nDigits-1)];
0N/A if ( q == '9' ){
0N/A while ( q == '9' && i > 0 ){
0N/A digits[i] = '0';
0N/A q = digits[--i];
0N/A }
0N/A if ( q == '9' ){
0N/A // carryout! High-order 1, rest 0s, larger exp.
0N/A decExponent += 1;
0N/A digits[0] = '1';
0N/A return;
0N/A }
0N/A // else fall through.
0N/A }
0N/A digits[i] = (char)(q+1);
0N/A }
0N/A
0N/A /*
0N/A * FIRST IMPORTANT CONSTRUCTOR: DOUBLE
0N/A */
0N/A public FloatingDecimal( double d )
0N/A {
0N/A long dBits = Double.doubleToLongBits( d );
0N/A long fractBits;
0N/A int binExp;
0N/A int nSignificantBits;
0N/A
0N/A // discover and delete sign
0N/A if ( (dBits&signMask) != 0 ){
0N/A isNegative = true;
0N/A dBits ^= signMask;
0N/A } else {
0N/A isNegative = false;
0N/A }
0N/A // Begin to unpack
0N/A // Discover obvious special cases of NaN and Infinity.
0N/A binExp = (int)( (dBits&expMask) >> expShift );
0N/A fractBits = dBits&fractMask;
0N/A if ( binExp == (int)(expMask>>expShift) ) {
0N/A isExceptional = true;
0N/A if ( fractBits == 0L ){
0N/A digits = infinity;
0N/A } else {
0N/A digits = notANumber;
0N/A isNegative = false; // NaN has no sign!
0N/A }
0N/A nDigits = digits.length;
0N/A return;
0N/A }
0N/A isExceptional = false;
0N/A // Finish unpacking
0N/A // Normalize denormalized numbers.
0N/A // Insert assumed high-order bit for normalized numbers.
0N/A // Subtract exponent bias.
0N/A if ( binExp == 0 ){
0N/A if ( fractBits == 0L ){
0N/A // not a denorm, just a 0!
0N/A decExponent = 0;
0N/A digits = zero;
0N/A nDigits = 1;
0N/A return;
0N/A }
0N/A while ( (fractBits&fractHOB) == 0L ){
0N/A fractBits <<= 1;
0N/A binExp -= 1;
0N/A }
0N/A nSignificantBits = expShift + binExp +1; // recall binExp is - shift count.
0N/A binExp += 1;
0N/A } else {
0N/A fractBits |= fractHOB;
0N/A nSignificantBits = expShift+1;
0N/A }
0N/A binExp -= expBias;
0N/A // call the routine that actually does all the hard work.
0N/A dtoa( binExp, fractBits, nSignificantBits );
0N/A }
0N/A
0N/A /*
0N/A * SECOND IMPORTANT CONSTRUCTOR: SINGLE
0N/A */
0N/A public FloatingDecimal( float f )
0N/A {
0N/A int fBits = Float.floatToIntBits( f );
0N/A int fractBits;
0N/A int binExp;
0N/A int nSignificantBits;
0N/A
0N/A // discover and delete sign
0N/A if ( (fBits&singleSignMask) != 0 ){
0N/A isNegative = true;
0N/A fBits ^= singleSignMask;
0N/A } else {
0N/A isNegative = false;
0N/A }
0N/A // Begin to unpack
0N/A // Discover obvious special cases of NaN and Infinity.
0N/A binExp = (int)( (fBits&singleExpMask) >> singleExpShift );
0N/A fractBits = fBits&singleFractMask;
0N/A if ( binExp == (int)(singleExpMask>>singleExpShift) ) {
0N/A isExceptional = true;
0N/A if ( fractBits == 0L ){
0N/A digits = infinity;
0N/A } else {
0N/A digits = notANumber;
0N/A isNegative = false; // NaN has no sign!
0N/A }
0N/A nDigits = digits.length;
0N/A return;
0N/A }
0N/A isExceptional = false;
0N/A // Finish unpacking
0N/A // Normalize denormalized numbers.
0N/A // Insert assumed high-order bit for normalized numbers.
0N/A // Subtract exponent bias.
0N/A if ( binExp == 0 ){
0N/A if ( fractBits == 0 ){
0N/A // not a denorm, just a 0!
0N/A decExponent = 0;
0N/A digits = zero;
0N/A nDigits = 1;
0N/A return;
0N/A }
0N/A while ( (fractBits&singleFractHOB) == 0 ){
0N/A fractBits <<= 1;
0N/A binExp -= 1;
0N/A }
0N/A nSignificantBits = singleExpShift + binExp +1; // recall binExp is - shift count.
0N/A binExp += 1;
0N/A } else {
0N/A fractBits |= singleFractHOB;
0N/A nSignificantBits = singleExpShift+1;
0N/A }
0N/A binExp -= singleExpBias;
0N/A // call the routine that actually does all the hard work.
0N/A dtoa( binExp, ((long)fractBits)<<(expShift-singleExpShift), nSignificantBits );
0N/A }
0N/A
0N/A private void
0N/A dtoa( int binExp, long fractBits, int nSignificantBits )
0N/A {
0N/A int nFractBits; // number of significant bits of fractBits;
0N/A int nTinyBits; // number of these to the right of the point.
0N/A int decExp;
0N/A
0N/A // Examine number. Determine if it is an easy case,
0N/A // which we can do pretty trivially using float/long conversion,
0N/A // or whether we must do real work.
0N/A nFractBits = countBits( fractBits );
0N/A nTinyBits = Math.max( 0, nFractBits - binExp - 1 );
0N/A if ( binExp <= maxSmallBinExp && binExp >= minSmallBinExp ){
0N/A // Look more closely at the number to decide if,
0N/A // with scaling by 10^nTinyBits, the result will fit in
0N/A // a long.
0N/A if ( (nTinyBits < long5pow.length) && ((nFractBits + n5bits[nTinyBits]) < 64 ) ){
0N/A /*
0N/A * We can do this:
0N/A * take the fraction bits, which are normalized.
0N/A * (a) nTinyBits == 0: Shift left or right appropriately
0N/A * to align the binary point at the extreme right, i.e.
0N/A * where a long int point is expected to be. The integer
0N/A * result is easily converted to a string.
0N/A * (b) nTinyBits > 0: Shift right by expShift-nFractBits,
0N/A * which effectively converts to long and scales by
0N/A * 2^nTinyBits. Then multiply by 5^nTinyBits to
0N/A * complete the scaling. We know this won't overflow
0N/A * because we just counted the number of bits necessary
0N/A * in the result. The integer you get from this can
0N/A * then be converted to a string pretty easily.
0N/A */
0N/A long halfULP;
0N/A if ( nTinyBits == 0 ) {
0N/A if ( binExp > nSignificantBits ){
0N/A halfULP = 1L << ( binExp-nSignificantBits-1);
0N/A } else {
0N/A halfULP = 0L;
0N/A }
0N/A if ( binExp >= expShift ){
0N/A fractBits <<= (binExp-expShift);
0N/A } else {
0N/A fractBits >>>= (expShift-binExp) ;
0N/A }
0N/A developLongDigits( 0, fractBits, halfULP );
0N/A return;
0N/A }
0N/A /*
0N/A * The following causes excess digits to be printed
0N/A * out in the single-float case. Our manipulation of
0N/A * halfULP here is apparently not correct. If we
0N/A * better understand how this works, perhaps we can
0N/A * use this special case again. But for the time being,
0N/A * we do not.
0N/A * else {
0N/A * fractBits >>>= expShift+1-nFractBits;
0N/A * fractBits *= long5pow[ nTinyBits ];
0N/A * halfULP = long5pow[ nTinyBits ] >> (1+nSignificantBits-nFractBits);
0N/A * developLongDigits( -nTinyBits, fractBits, halfULP );
0N/A * return;
0N/A * }
0N/A */
0N/A }
0N/A }
0N/A /*
0N/A * This is the hard case. We are going to compute large positive
0N/A * integers B and S and integer decExp, s.t.
0N/A * d = ( B / S ) * 10^decExp
0N/A * 1 <= B / S < 10
0N/A * Obvious choices are:
0N/A * decExp = floor( log10(d) )
0N/A * B = d * 2^nTinyBits * 10^max( 0, -decExp )
0N/A * S = 10^max( 0, decExp) * 2^nTinyBits
0N/A * (noting that nTinyBits has already been forced to non-negative)
0N/A * I am also going to compute a large positive integer
0N/A * M = (1/2^nSignificantBits) * 2^nTinyBits * 10^max( 0, -decExp )
0N/A * i.e. M is (1/2) of the ULP of d, scaled like B.
0N/A * When we iterate through dividing B/S and picking off the
0N/A * quotient bits, we will know when to stop when the remainder
0N/A * is <= M.
0N/A *
0N/A * We keep track of powers of 2 and powers of 5.
0N/A */
0N/A
0N/A /*
0N/A * Estimate decimal exponent. (If it is small-ish,
0N/A * we could double-check.)
0N/A *
0N/A * First, scale the mantissa bits such that 1 <= d2 < 2.
0N/A * We are then going to estimate
0N/A * log10(d2) ~=~ (d2-1.5)/1.5 + log(1.5)
0N/A * and so we can estimate
0N/A * log10(d) ~=~ log10(d2) + binExp * log10(2)
0N/A * take the floor and call it decExp.
0N/A * FIXME -- use more precise constants here. It costs no more.
0N/A */
0N/A double d2 = Double.longBitsToDouble(
0N/A expOne | ( fractBits &~ fractHOB ) );
0N/A decExp = (int)Math.floor(
0N/A (d2-1.5D)*0.289529654D + 0.176091259 + (double)binExp * 0.301029995663981 );
0N/A int B2, B5; // powers of 2 and powers of 5, respectively, in B
0N/A int S2, S5; // powers of 2 and powers of 5, respectively, in S
0N/A int M2, M5; // powers of 2 and powers of 5, respectively, in M
0N/A int Bbits; // binary digits needed to represent B, approx.
0N/A int tenSbits; // binary digits needed to represent 10*S, approx.
0N/A FDBigInt Sval, Bval, Mval;
0N/A
0N/A B5 = Math.max( 0, -decExp );
0N/A B2 = B5 + nTinyBits + binExp;
0N/A
0N/A S5 = Math.max( 0, decExp );
0N/A S2 = S5 + nTinyBits;
0N/A
0N/A M5 = B5;
0N/A M2 = B2 - nSignificantBits;
0N/A
0N/A /*
0N/A * the long integer fractBits contains the (nFractBits) interesting
0N/A * bits from the mantissa of d ( hidden 1 added if necessary) followed
0N/A * by (expShift+1-nFractBits) zeros. In the interest of compactness,
0N/A * I will shift out those zeros before turning fractBits into a
0N/A * FDBigInt. The resulting whole number will be
0N/A * d * 2^(nFractBits-1-binExp).
0N/A */
0N/A fractBits >>>= (expShift+1-nFractBits);
0N/A B2 -= nFractBits-1;
0N/A int common2factor = Math.min( B2, S2 );
0N/A B2 -= common2factor;
0N/A S2 -= common2factor;
0N/A M2 -= common2factor;
0N/A
0N/A /*
0N/A * HACK!! For exact powers of two, the next smallest number
0N/A * is only half as far away as we think (because the meaning of
0N/A * ULP changes at power-of-two bounds) for this reason, we
0N/A * hack M2. Hope this works.
0N/A */
0N/A if ( nFractBits == 1 )
0N/A M2 -= 1;
0N/A
0N/A if ( M2 < 0 ){
0N/A // oops.
0N/A // since we cannot scale M down far enough,
0N/A // we must scale the other values up.
0N/A B2 -= M2;
0N/A S2 -= M2;
0N/A M2 = 0;
0N/A }
0N/A /*
0N/A * Construct, Scale, iterate.
0N/A * Some day, we'll write a stopping test that takes
0N/A * account of the asymmetry of the spacing of floating-point
0N/A * numbers below perfect powers of 2
0N/A * 26 Sept 96 is not that day.
0N/A * So we use a symmetric test.
0N/A */
0N/A char digits[] = this.digits = new char[18];
0N/A int ndigit = 0;
0N/A boolean low, high;
0N/A long lowDigitDifference;
0N/A int q;
0N/A
0N/A /*
0N/A * Detect the special cases where all the numbers we are about
0N/A * to compute will fit in int or long integers.
0N/A * In these cases, we will avoid doing FDBigInt arithmetic.
0N/A * We use the same algorithms, except that we "normalize"
0N/A * our FDBigInts before iterating. This is to make division easier,
0N/A * as it makes our fist guess (quotient of high-order words)
0N/A * more accurate!
0N/A *
0N/A * Some day, we'll write a stopping test that takes
0N/A * account of the asymmetry of the spacing of floating-point
0N/A * numbers below perfect powers of 2
0N/A * 26 Sept 96 is not that day.
0N/A * So we use a symmetric test.
0N/A */
0N/A Bbits = nFractBits + B2 + (( B5 < n5bits.length )? n5bits[B5] : ( B5*3 ));
0N/A tenSbits = S2+1 + (( (S5+1) < n5bits.length )? n5bits[(S5+1)] : ( (S5+1)*3 ));
0N/A if ( Bbits < 64 && tenSbits < 64){
0N/A if ( Bbits < 32 && tenSbits < 32){
0N/A // wa-hoo! They're all ints!
0N/A int b = ((int)fractBits * small5pow[B5] ) << B2;
0N/A int s = small5pow[S5] << S2;
0N/A int m = small5pow[M5] << M2;
0N/A int tens = s * 10;
0N/A /*
0N/A * Unroll the first iteration. If our decExp estimate
0N/A * was too high, our first quotient will be zero. In this
0N/A * case, we discard it and decrement decExp.
0N/A */
0N/A ndigit = 0;
0N/A q = b / s;
0N/A b = 10 * ( b % s );
0N/A m *= 10;
0N/A low = (b < m );
0N/A high = (b+m > tens );
0N/A assert q < 10 : q; // excessively large digit
0N/A if ( (q == 0) && ! high ){
0N/A // oops. Usually ignore leading zero.
0N/A decExp--;
0N/A } else {
0N/A digits[ndigit++] = (char)('0' + q);
0N/A }
0N/A /*
0N/A * HACK! Java spec sez that we always have at least
0N/A * one digit after the . in either F- or E-form output.
0N/A * Thus we will need more than one digit if we're using
0N/A * E-form
0N/A */
1759N/A if ( decExp < -3 || decExp >= 8 ){
0N/A high = low = false;
0N/A }
0N/A while( ! low && ! high ){
0N/A q = b / s;
0N/A b = 10 * ( b % s );
0N/A m *= 10;
0N/A assert q < 10 : q; // excessively large digit
0N/A if ( m > 0L ){
0N/A low = (b < m );
0N/A high = (b+m > tens );
0N/A } else {
0N/A // hack -- m might overflow!
0N/A // in this case, it is certainly > b,
0N/A // which won't
0N/A // and b+m > tens, too, since that has overflowed
0N/A // either!
0N/A low = true;
0N/A high = true;
0N/A }
0N/A digits[ndigit++] = (char)('0' + q);
0N/A }
0N/A lowDigitDifference = (b<<1) - tens;
0N/A } else {
0N/A // still good! they're all longs!
0N/A long b = (fractBits * long5pow[B5] ) << B2;
0N/A long s = long5pow[S5] << S2;
0N/A long m = long5pow[M5] << M2;
0N/A long tens = s * 10L;
0N/A /*
0N/A * Unroll the first iteration. If our decExp estimate
0N/A * was too high, our first quotient will be zero. In this
0N/A * case, we discard it and decrement decExp.
0N/A */
0N/A ndigit = 0;
0N/A q = (int) ( b / s );
0N/A b = 10L * ( b % s );
0N/A m *= 10L;
0N/A low = (b < m );
0N/A high = (b+m > tens );
0N/A assert q < 10 : q; // excessively large digit
0N/A if ( (q == 0) && ! high ){
0N/A // oops. Usually ignore leading zero.
0N/A decExp--;
0N/A } else {
0N/A digits[ndigit++] = (char)('0' + q);
0N/A }
0N/A /*
0N/A * HACK! Java spec sez that we always have at least
0N/A * one digit after the . in either F- or E-form output.
0N/A * Thus we will need more than one digit if we're using
0N/A * E-form
0N/A */
1759N/A if ( decExp < -3 || decExp >= 8 ){
0N/A high = low = false;
0N/A }
0N/A while( ! low && ! high ){
0N/A q = (int) ( b / s );
0N/A b = 10 * ( b % s );
0N/A m *= 10;
0N/A assert q < 10 : q; // excessively large digit
0N/A if ( m > 0L ){
0N/A low = (b < m );
0N/A high = (b+m > tens );
0N/A } else {
0N/A // hack -- m might overflow!
0N/A // in this case, it is certainly > b,
0N/A // which won't
0N/A // and b+m > tens, too, since that has overflowed
0N/A // either!
0N/A low = true;
0N/A high = true;
0N/A }
0N/A digits[ndigit++] = (char)('0' + q);
0N/A }
0N/A lowDigitDifference = (b<<1) - tens;
0N/A }
0N/A } else {
0N/A FDBigInt tenSval;
0N/A int shiftBias;
0N/A
0N/A /*
0N/A * We really must do FDBigInt arithmetic.
0N/A * Fist, construct our FDBigInt initial values.
0N/A */
0N/A Bval = multPow52( new FDBigInt( fractBits ), B5, B2 );
0N/A Sval = constructPow52( S5, S2 );
0N/A Mval = constructPow52( M5, M2 );
0N/A
0N/A
0N/A // normalize so that division works better
0N/A Bval.lshiftMe( shiftBias = Sval.normalizeMe() );
0N/A Mval.lshiftMe( shiftBias );
0N/A tenSval = Sval.mult( 10 );
0N/A /*
0N/A * Unroll the first iteration. If our decExp estimate
0N/A * was too high, our first quotient will be zero. In this
0N/A * case, we discard it and decrement decExp.
0N/A */
0N/A ndigit = 0;
0N/A q = Bval.quoRemIteration( Sval );
0N/A Mval = Mval.mult( 10 );
0N/A low = (Bval.cmp( Mval ) < 0);
0N/A high = (Bval.add( Mval ).cmp( tenSval ) > 0 );
0N/A assert q < 10 : q; // excessively large digit
0N/A if ( (q == 0) && ! high ){
0N/A // oops. Usually ignore leading zero.
0N/A decExp--;
0N/A } else {
0N/A digits[ndigit++] = (char)('0' + q);
0N/A }
0N/A /*
0N/A * HACK! Java spec sez that we always have at least
0N/A * one digit after the . in either F- or E-form output.
0N/A * Thus we will need more than one digit if we're using
0N/A * E-form
0N/A */
1759N/A if ( decExp < -3 || decExp >= 8 ){
0N/A high = low = false;
0N/A }
0N/A while( ! low && ! high ){
0N/A q = Bval.quoRemIteration( Sval );
0N/A Mval = Mval.mult( 10 );
0N/A assert q < 10 : q; // excessively large digit
0N/A low = (Bval.cmp( Mval ) < 0);
0N/A high = (Bval.add( Mval ).cmp( tenSval ) > 0 );
0N/A digits[ndigit++] = (char)('0' + q);
0N/A }
0N/A if ( high && low ){
0N/A Bval.lshiftMe(1);
0N/A lowDigitDifference = Bval.cmp(tenSval);
0N/A } else
0N/A lowDigitDifference = 0L; // this here only for flow analysis!
0N/A }
0N/A this.decExponent = decExp+1;
0N/A this.digits = digits;
0N/A this.nDigits = ndigit;
0N/A /*
0N/A * Last digit gets rounded based on stopping condition.
0N/A */
0N/A if ( high ){
0N/A if ( low ){
0N/A if ( lowDigitDifference == 0L ){
0N/A // it's a tie!
0N/A // choose based on which digits we like.
0N/A if ( (digits[nDigits-1]&1) != 0 ) roundup();
0N/A } else if ( lowDigitDifference > 0 ){
0N/A roundup();
0N/A }
0N/A } else {
0N/A roundup();
0N/A }
0N/A }
0N/A }
0N/A
0N/A public String
0N/A toString(){
0N/A // most brain-dead version
0N/A StringBuffer result = new StringBuffer( nDigits+8 );
0N/A if ( isNegative ){ result.append( '-' ); }
0N/A if ( isExceptional ){
0N/A result.append( digits, 0, nDigits );
0N/A } else {
0N/A result.append( "0.");
0N/A result.append( digits, 0, nDigits );
0N/A result.append('e');
0N/A result.append( decExponent );
0N/A }
0N/A return new String(result);
0N/A }
0N/A
0N/A public String toJavaFormatString() {
0N/A char result[] = (char[])(perThreadBuffer.get());
0N/A int i = getChars(result);
0N/A return new String(result, 0, i);
0N/A }
0N/A
0N/A private int getChars(char[] result) {
0N/A assert nDigits <= 19 : nDigits; // generous bound on size of nDigits
0N/A int i = 0;
0N/A if (isNegative) { result[0] = '-'; i = 1; }
0N/A if (isExceptional) {
0N/A System.arraycopy(digits, 0, result, i, nDigits);
0N/A i += nDigits;
0N/A } else {
0N/A if (decExponent > 0 && decExponent < 8) {
0N/A // print digits.digits.
0N/A int charLength = Math.min(nDigits, decExponent);
0N/A System.arraycopy(digits, 0, result, i, charLength);
0N/A i += charLength;
0N/A if (charLength < decExponent) {
0N/A charLength = decExponent-charLength;
0N/A System.arraycopy(zero, 0, result, i, charLength);
0N/A i += charLength;
0N/A result[i++] = '.';
0N/A result[i++] = '0';
0N/A } else {
0N/A result[i++] = '.';
0N/A if (charLength < nDigits) {
0N/A int t = nDigits - charLength;
0N/A System.arraycopy(digits, charLength, result, i, t);
0N/A i += t;
0N/A } else {
0N/A result[i++] = '0';
0N/A }
0N/A }
0N/A } else if (decExponent <=0 && decExponent > -3) {
0N/A result[i++] = '0';
0N/A result[i++] = '.';
0N/A if (decExponent != 0) {
0N/A System.arraycopy(zero, 0, result, i, -decExponent);
0N/A i -= decExponent;
0N/A }
0N/A System.arraycopy(digits, 0, result, i, nDigits);
0N/A i += nDigits;
0N/A } else {
0N/A result[i++] = digits[0];
0N/A result[i++] = '.';
0N/A if (nDigits > 1) {
0N/A System.arraycopy(digits, 1, result, i, nDigits-1);
0N/A i += nDigits-1;
0N/A } else {
0N/A result[i++] = '0';
0N/A }
0N/A result[i++] = 'E';
0N/A int e;
0N/A if (decExponent <= 0) {
0N/A result[i++] = '-';
0N/A e = -decExponent+1;
0N/A } else {
0N/A e = decExponent-1;
0N/A }
0N/A // decExponent has 1, 2, or 3, digits
0N/A if (e <= 9) {
0N/A result[i++] = (char)(e+'0');
0N/A } else if (e <= 99) {
0N/A result[i++] = (char)(e/10 +'0');
0N/A result[i++] = (char)(e%10 + '0');
0N/A } else {
0N/A result[i++] = (char)(e/100+'0');
0N/A e %= 100;
0N/A result[i++] = (char)(e/10+'0');
0N/A result[i++] = (char)(e%10 + '0');
0N/A }
0N/A }
0N/A }
0N/A return i;
0N/A }
0N/A
0N/A // Per-thread buffer for string/stringbuffer conversion
0N/A private static ThreadLocal perThreadBuffer = new ThreadLocal() {
0N/A protected synchronized Object initialValue() {
0N/A return new char[26];
0N/A }
0N/A };
0N/A
0N/A public void appendTo(Appendable buf) {
0N/A char result[] = (char[])(perThreadBuffer.get());
0N/A int i = getChars(result);
0N/A if (buf instanceof StringBuilder)
0N/A ((StringBuilder) buf).append(result, 0, i);
0N/A else if (buf instanceof StringBuffer)
0N/A ((StringBuffer) buf).append(result, 0, i);
0N/A else
0N/A assert false;
0N/A }
0N/A
0N/A public static FloatingDecimal
0N/A readJavaFormatString( String in ) throws NumberFormatException {
0N/A boolean isNegative = false;
0N/A boolean signSeen = false;
0N/A int decExp;
0N/A char c;
0N/A
0N/A parseNumber:
0N/A try{
0N/A in = in.trim(); // don't fool around with white space.
0N/A // throws NullPointerException if null
0N/A int l = in.length();
0N/A if ( l == 0 ) throw new NumberFormatException("empty String");
0N/A int i = 0;
0N/A switch ( c = in.charAt( i ) ){
0N/A case '-':
0N/A isNegative = true;
0N/A //FALLTHROUGH
0N/A case '+':
0N/A i++;
0N/A signSeen = true;
0N/A }
0N/A
0N/A // Check for NaN and Infinity strings
0N/A c = in.charAt(i);
0N/A if(c == 'N' || c == 'I') { // possible NaN or infinity
0N/A boolean potentialNaN = false;
0N/A char targetChars[] = null; // char array of "NaN" or "Infinity"
0N/A
0N/A if(c == 'N') {
0N/A targetChars = notANumber;
0N/A potentialNaN = true;
0N/A } else {
0N/A targetChars = infinity;
0N/A }
0N/A
0N/A // compare Input string to "NaN" or "Infinity"
0N/A int j = 0;
0N/A while(i < l && j < targetChars.length) {
0N/A if(in.charAt(i) == targetChars[j]) {
0N/A i++; j++;
0N/A }
0N/A else // something is amiss, throw exception
0N/A break parseNumber;
0N/A }
0N/A
0N/A // For the candidate string to be a NaN or infinity,
0N/A // all characters in input string and target char[]
0N/A // must be matched ==> j must equal targetChars.length
0N/A // and i must equal l
0N/A if( (j == targetChars.length) && (i == l) ) { // return NaN or infinity
0N/A return (potentialNaN ? new FloatingDecimal(Double.NaN) // NaN has no sign
0N/A : new FloatingDecimal(isNegative?
0N/A Double.NEGATIVE_INFINITY:
0N/A Double.POSITIVE_INFINITY)) ;
0N/A }
0N/A else { // something went wrong, throw exception
0N/A break parseNumber;
0N/A }
0N/A
0N/A } else if (c == '0') { // check for hexadecimal floating-point number
0N/A if (l > i+1 ) {
0N/A char ch = in.charAt(i+1);
0N/A if (ch == 'x' || ch == 'X' ) // possible hex string
0N/A return parseHexString(in);
0N/A }
0N/A } // look for and process decimal floating-point string
0N/A
0N/A char[] digits = new char[ l ];
0N/A int nDigits= 0;
0N/A boolean decSeen = false;
0N/A int decPt = 0;
0N/A int nLeadZero = 0;
0N/A int nTrailZero= 0;
0N/A digitLoop:
0N/A while ( i < l ){
0N/A switch ( c = in.charAt( i ) ){
0N/A case '0':
0N/A if ( nDigits > 0 ){
0N/A nTrailZero += 1;
0N/A } else {
0N/A nLeadZero += 1;
0N/A }
0N/A break; // out of switch.
0N/A case '1':
0N/A case '2':
0N/A case '3':
0N/A case '4':
0N/A case '5':
0N/A case '6':
0N/A case '7':
0N/A case '8':
0N/A case '9':
0N/A while ( nTrailZero > 0 ){
0N/A digits[nDigits++] = '0';
0N/A nTrailZero -= 1;
0N/A }
0N/A digits[nDigits++] = c;
0N/A break; // out of switch.
0N/A case '.':
0N/A if ( decSeen ){
0N/A // already saw one ., this is the 2nd.
0N/A throw new NumberFormatException("multiple points");
0N/A }
0N/A decPt = i;
0N/A if ( signSeen ){
0N/A decPt -= 1;
0N/A }
0N/A decSeen = true;
0N/A break; // out of switch.
0N/A default:
0N/A break digitLoop;
0N/A }
0N/A i++;
0N/A }
0N/A /*
0N/A * At this point, we've scanned all the digits and decimal
0N/A * point we're going to see. Trim off leading and trailing
0N/A * zeros, which will just confuse us later, and adjust
0N/A * our initial decimal exponent accordingly.
0N/A * To review:
0N/A * we have seen i total characters.
0N/A * nLeadZero of them were zeros before any other digits.
0N/A * nTrailZero of them were zeros after any other digits.
0N/A * if ( decSeen ), then a . was seen after decPt characters
0N/A * ( including leading zeros which have been discarded )
0N/A * nDigits characters were neither lead nor trailing
0N/A * zeros, nor point
0N/A */
0N/A /*
0N/A * special hack: if we saw no non-zero digits, then the
0N/A * answer is zero!
0N/A * Unfortunately, we feel honor-bound to keep parsing!
0N/A */
0N/A if ( nDigits == 0 ){
0N/A digits = zero;
0N/A nDigits = 1;
0N/A if ( nLeadZero == 0 ){
0N/A // we saw NO DIGITS AT ALL,
0N/A // not even a crummy 0!
0N/A // this is not allowed.
0N/A break parseNumber; // go throw exception
0N/A }
0N/A
0N/A }
0N/A
0N/A /* Our initial exponent is decPt, adjusted by the number of
0N/A * discarded zeros. Or, if there was no decPt,
0N/A * then its just nDigits adjusted by discarded trailing zeros.
0N/A */
0N/A if ( decSeen ){
0N/A decExp = decPt - nLeadZero;
0N/A } else {
0N/A decExp = nDigits+nTrailZero;
0N/A }
0N/A
0N/A /*
0N/A * Look for 'e' or 'E' and an optionally signed integer.
0N/A */
0N/A if ( (i < l) && (((c = in.charAt(i) )=='e') || (c == 'E') ) ){
0N/A int expSign = 1;
0N/A int expVal = 0;
0N/A int reallyBig = Integer.MAX_VALUE / 10;
0N/A boolean expOverflow = false;
0N/A switch( in.charAt(++i) ){
0N/A case '-':
0N/A expSign = -1;
0N/A //FALLTHROUGH
0N/A case '+':
0N/A i++;
0N/A }
0N/A int expAt = i;
0N/A expLoop:
0N/A while ( i < l ){
0N/A if ( expVal >= reallyBig ){
0N/A // the next character will cause integer
0N/A // overflow.
0N/A expOverflow = true;
0N/A }
0N/A switch ( c = in.charAt(i++) ){
0N/A case '0':
0N/A case '1':
0N/A case '2':
0N/A case '3':
0N/A case '4':
0N/A case '5':
0N/A case '6':
0N/A case '7':
0N/A case '8':
0N/A case '9':
0N/A expVal = expVal*10 + ( (int)c - (int)'0' );
0N/A continue;
0N/A default:
0N/A i--; // back up.
0N/A break expLoop; // stop parsing exponent.
0N/A }
0N/A }
0N/A int expLimit = bigDecimalExponent+nDigits+nTrailZero;
0N/A if ( expOverflow || ( expVal > expLimit ) ){
0N/A //
0N/A // The intent here is to end up with
0N/A // infinity or zero, as appropriate.
0N/A // The reason for yielding such a small decExponent,
0N/A // rather than something intuitive such as
0N/A // expSign*Integer.MAX_VALUE, is that this value
0N/A // is subject to further manipulation in
0N/A // doubleValue() and floatValue(), and I don't want
0N/A // it to be able to cause overflow there!
0N/A // (The only way we can get into trouble here is for
0N/A // really outrageous nDigits+nTrailZero, such as 2 billion. )
0N/A //
0N/A decExp = expSign*expLimit;
0N/A } else {
0N/A // this should not overflow, since we tested
0N/A // for expVal > (MAX+N), where N >= abs(decExp)
0N/A decExp = decExp + expSign*expVal;
0N/A }
0N/A
0N/A // if we saw something not a digit ( or end of string )
0N/A // after the [Ee][+-], without seeing any digits at all
0N/A // this is certainly an error. If we saw some digits,
0N/A // but then some trailing garbage, that might be ok.
0N/A // so we just fall through in that case.
0N/A // HUMBUG
0N/A if ( i == expAt )
0N/A break parseNumber; // certainly bad
0N/A }
0N/A /*
0N/A * We parsed everything we could.
0N/A * If there are leftovers, then this is not good input!
0N/A */
0N/A if ( i < l &&
0N/A ((i != l - 1) ||
0N/A (in.charAt(i) != 'f' &&
0N/A in.charAt(i) != 'F' &&
0N/A in.charAt(i) != 'd' &&
0N/A in.charAt(i) != 'D'))) {
0N/A break parseNumber; // go throw exception
0N/A }
0N/A
0N/A return new FloatingDecimal( isNegative, decExp, digits, nDigits, false );
0N/A } catch ( StringIndexOutOfBoundsException e ){ }
0N/A throw new NumberFormatException("For input string: \"" + in + "\"");
0N/A }
0N/A
0N/A /*
0N/A * Take a FloatingDecimal, which we presumably just scanned in,
0N/A * and find out what its value is, as a double.
0N/A *
0N/A * AS A SIDE EFFECT, SET roundDir TO INDICATE PREFERRED
0N/A * ROUNDING DIRECTION in case the result is really destined
0N/A * for a single-precision float.
0N/A */
0N/A
4124N/A public strictfp double doubleValue(){
0N/A int kDigits = Math.min( nDigits, maxDecimalDigits+1 );
0N/A long lValue;
0N/A double dValue;
0N/A double rValue, tValue;
0N/A
0N/A // First, check for NaN and Infinity values
0N/A if(digits == infinity || digits == notANumber) {
0N/A if(digits == notANumber)
0N/A return Double.NaN;
0N/A else
0N/A return (isNegative?Double.NEGATIVE_INFINITY:Double.POSITIVE_INFINITY);
0N/A }
0N/A else {
0N/A if (mustSetRoundDir) {
0N/A roundDir = 0;
0N/A }
0N/A /*
0N/A * convert the lead kDigits to a long integer.
0N/A */
0N/A // (special performance hack: start to do it using int)
0N/A int iValue = (int)digits[0]-(int)'0';
0N/A int iDigits = Math.min( kDigits, intDecimalDigits );
0N/A for ( int i=1; i < iDigits; i++ ){
0N/A iValue = iValue*10 + (int)digits[i]-(int)'0';
0N/A }
0N/A lValue = (long)iValue;
0N/A for ( int i=iDigits; i < kDigits; i++ ){
0N/A lValue = lValue*10L + (long)((int)digits[i]-(int)'0');
0N/A }
0N/A dValue = (double)lValue;
0N/A int exp = decExponent-kDigits;
0N/A /*
0N/A * lValue now contains a long integer with the value of
0N/A * the first kDigits digits of the number.
0N/A * dValue contains the (double) of the same.
0N/A */
0N/A
0N/A if ( nDigits <= maxDecimalDigits ){
0N/A /*
0N/A * possibly an easy case.
0N/A * We know that the digits can be represented
0N/A * exactly. And if the exponent isn't too outrageous,
0N/A * the whole thing can be done with one operation,
0N/A * thus one rounding error.
0N/A * Note that all our constructors trim all leading and
0N/A * trailing zeros, so simple values (including zero)
0N/A * will always end up here
0N/A */
0N/A if (exp == 0 || dValue == 0.0)
0N/A return (isNegative)? -dValue : dValue; // small floating integer
0N/A else if ( exp >= 0 ){
0N/A if ( exp <= maxSmallTen ){
0N/A /*
0N/A * Can get the answer with one operation,
0N/A * thus one roundoff.
0N/A */
0N/A rValue = dValue * small10pow[exp];
0N/A if ( mustSetRoundDir ){
0N/A tValue = rValue / small10pow[exp];
0N/A roundDir = ( tValue == dValue ) ? 0
0N/A :( tValue < dValue ) ? 1
0N/A : -1;
0N/A }
0N/A return (isNegative)? -rValue : rValue;
0N/A }
0N/A int slop = maxDecimalDigits - kDigits;
0N/A if ( exp <= maxSmallTen+slop ){
0N/A /*
0N/A * We can multiply dValue by 10^(slop)
0N/A * and it is still "small" and exact.
0N/A * Then we can multiply by 10^(exp-slop)
0N/A * with one rounding.
0N/A */
0N/A dValue *= small10pow[slop];
0N/A rValue = dValue * small10pow[exp-slop];
0N/A
0N/A if ( mustSetRoundDir ){
0N/A tValue = rValue / small10pow[exp-slop];
0N/A roundDir = ( tValue == dValue ) ? 0
0N/A :( tValue < dValue ) ? 1
0N/A : -1;
0N/A }
0N/A return (isNegative)? -rValue : rValue;
0N/A }
0N/A /*
0N/A * Else we have a hard case with a positive exp.
0N/A */
0N/A } else {
0N/A if ( exp >= -maxSmallTen ){
0N/A /*
0N/A * Can get the answer in one division.
0N/A */
0N/A rValue = dValue / small10pow[-exp];
0N/A tValue = rValue * small10pow[-exp];
0N/A if ( mustSetRoundDir ){
0N/A roundDir = ( tValue == dValue ) ? 0
0N/A :( tValue < dValue ) ? 1
0N/A : -1;
0N/A }
0N/A return (isNegative)? -rValue : rValue;
0N/A }
0N/A /*
0N/A * Else we have a hard case with a negative exp.
0N/A */
0N/A }
0N/A }
0N/A
0N/A /*
0N/A * Harder cases:
0N/A * The sum of digits plus exponent is greater than
0N/A * what we think we can do with one error.
0N/A *
0N/A * Start by approximating the right answer by,
0N/A * naively, scaling by powers of 10.
0N/A */
0N/A if ( exp > 0 ){
0N/A if ( decExponent > maxDecimalExponent+1 ){
0N/A /*
0N/A * Lets face it. This is going to be
0N/A * Infinity. Cut to the chase.
0N/A */
0N/A return (isNegative)? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
0N/A }
0N/A if ( (exp&15) != 0 ){
0N/A dValue *= small10pow[exp&15];
0N/A }
0N/A if ( (exp>>=4) != 0 ){
0N/A int j;
0N/A for( j = 0; exp > 1; j++, exp>>=1 ){
0N/A if ( (exp&1)!=0)
0N/A dValue *= big10pow[j];
0N/A }
0N/A /*
0N/A * The reason for the weird exp > 1 condition
0N/A * in the above loop was so that the last multiply
0N/A * would get unrolled. We handle it here.
0N/A * It could overflow.
0N/A */
0N/A double t = dValue * big10pow[j];
0N/A if ( Double.isInfinite( t ) ){
0N/A /*
0N/A * It did overflow.
0N/A * Look more closely at the result.
0N/A * If the exponent is just one too large,
0N/A * then use the maximum finite as our estimate
0N/A * value. Else call the result infinity
0N/A * and punt it.
0N/A * ( I presume this could happen because
0N/A * rounding forces the result here to be
0N/A * an ULP or two larger than
0N/A * Double.MAX_VALUE ).
0N/A */
0N/A t = dValue / 2.0;
0N/A t *= big10pow[j];
0N/A if ( Double.isInfinite( t ) ){
0N/A return (isNegative)? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
0N/A }
0N/A t = Double.MAX_VALUE;
0N/A }
0N/A dValue = t;
0N/A }
0N/A } else if ( exp < 0 ){
0N/A exp = -exp;
0N/A if ( decExponent < minDecimalExponent-1 ){
0N/A /*
0N/A * Lets face it. This is going to be
0N/A * zero. Cut to the chase.
0N/A */
0N/A return (isNegative)? -0.0 : 0.0;
0N/A }
0N/A if ( (exp&15) != 0 ){
0N/A dValue /= small10pow[exp&15];
0N/A }
0N/A if ( (exp>>=4) != 0 ){
0N/A int j;
0N/A for( j = 0; exp > 1; j++, exp>>=1 ){
0N/A if ( (exp&1)!=0)
0N/A dValue *= tiny10pow[j];
0N/A }
0N/A /*
0N/A * The reason for the weird exp > 1 condition
0N/A * in the above loop was so that the last multiply
0N/A * would get unrolled. We handle it here.
0N/A * It could underflow.
0N/A */
0N/A double t = dValue * tiny10pow[j];
0N/A if ( t == 0.0 ){
0N/A /*
0N/A * It did underflow.
0N/A * Look more closely at the result.
0N/A * If the exponent is just one too small,
0N/A * then use the minimum finite as our estimate
0N/A * value. Else call the result 0.0
0N/A * and punt it.
0N/A * ( I presume this could happen because
0N/A * rounding forces the result here to be
0N/A * an ULP or two less than
0N/A * Double.MIN_VALUE ).
0N/A */
0N/A t = dValue * 2.0;
0N/A t *= tiny10pow[j];
0N/A if ( t == 0.0 ){
0N/A return (isNegative)? -0.0 : 0.0;
0N/A }
0N/A t = Double.MIN_VALUE;
0N/A }
0N/A dValue = t;
0N/A }
0N/A }
0N/A
0N/A /*
0N/A * dValue is now approximately the result.
0N/A * The hard part is adjusting it, by comparison
0N/A * with FDBigInt arithmetic.
0N/A * Formulate the EXACT big-number result as
0N/A * bigD0 * 10^exp
0N/A */
0N/A FDBigInt bigD0 = new FDBigInt( lValue, digits, kDigits, nDigits );
0N/A exp = decExponent - nDigits;
0N/A
0N/A correctionLoop:
0N/A while(true){
0N/A /* AS A SIDE EFFECT, THIS METHOD WILL SET THE INSTANCE VARIABLES
0N/A * bigIntExp and bigIntNBits
0N/A */
0N/A FDBigInt bigB = doubleToBigInt( dValue );
0N/A
0N/A /*
0N/A * Scale bigD, bigB appropriately for
0N/A * big-integer operations.
0N/A * Naively, we multiply by powers of ten
0N/A * and powers of two. What we actually do
0N/A * is keep track of the powers of 5 and
0N/A * powers of 2 we would use, then factor out
0N/A * common divisors before doing the work.
0N/A */
0N/A int B2, B5; // powers of 2, 5 in bigB
0N/A int D2, D5; // powers of 2, 5 in bigD
0N/A int Ulp2; // powers of 2 in halfUlp.
0N/A if ( exp >= 0 ){
0N/A B2 = B5 = 0;
0N/A D2 = D5 = exp;
0N/A } else {
0N/A B2 = B5 = -exp;
0N/A D2 = D5 = 0;
0N/A }
0N/A if ( bigIntExp >= 0 ){
0N/A B2 += bigIntExp;
0N/A } else {
0N/A D2 -= bigIntExp;
0N/A }
0N/A Ulp2 = B2;
0N/A // shift bigB and bigD left by a number s. t.
0N/A // halfUlp is still an integer.
0N/A int hulpbias;
0N/A if ( bigIntExp+bigIntNBits <= -expBias+1 ){
0N/A // This is going to be a denormalized number
0N/A // (if not actually zero).
0N/A // half an ULP is at 2^-(expBias+expShift+1)
0N/A hulpbias = bigIntExp+ expBias + expShift;
0N/A } else {
0N/A hulpbias = expShift + 2 - bigIntNBits;
0N/A }
0N/A B2 += hulpbias;
0N/A D2 += hulpbias;
0N/A // if there are common factors of 2, we might just as well
0N/A // factor them out, as they add nothing useful.
0N/A int common2 = Math.min( B2, Math.min( D2, Ulp2 ) );
0N/A B2 -= common2;
0N/A D2 -= common2;
0N/A Ulp2 -= common2;
0N/A // do multiplications by powers of 5 and 2
0N/A bigB = multPow52( bigB, B5, B2 );
0N/A FDBigInt bigD = multPow52( new FDBigInt( bigD0 ), D5, D2 );
0N/A //
0N/A // to recap:
0N/A // bigB is the scaled-big-int version of our floating-point
0N/A // candidate.
0N/A // bigD is the scaled-big-int version of the exact value
0N/A // as we understand it.
0N/A // halfUlp is 1/2 an ulp of bigB, except for special cases
0N/A // of exact powers of 2
0N/A //
0N/A // the plan is to compare bigB with bigD, and if the difference
0N/A // is less than halfUlp, then we're satisfied. Otherwise,
0N/A // use the ratio of difference to halfUlp to calculate a fudge
0N/A // factor to add to the floating value, then go 'round again.
0N/A //
0N/A FDBigInt diff;
0N/A int cmpResult;
0N/A boolean overvalue;
0N/A if ( (cmpResult = bigB.cmp( bigD ) ) > 0 ){
0N/A overvalue = true; // our candidate is too big.
0N/A diff = bigB.sub( bigD );
3502N/A if ( (bigIntNBits == 1) && (bigIntExp > -expBias+1) ){
0N/A // candidate is a normalized exact power of 2 and
0N/A // is too big. We will be subtracting.
0N/A // For our purposes, ulp is the ulp of the
0N/A // next smaller range.
0N/A Ulp2 -= 1;
0N/A if ( Ulp2 < 0 ){
0N/A // rats. Cannot de-scale ulp this far.
0N/A // must scale diff in other direction.
0N/A Ulp2 = 0;
0N/A diff.lshiftMe( 1 );
0N/A }
0N/A }
0N/A } else if ( cmpResult < 0 ){
0N/A overvalue = false; // our candidate is too small.
0N/A diff = bigD.sub( bigB );
0N/A } else {
0N/A // the candidate is exactly right!
0N/A // this happens with surprising frequency
0N/A break correctionLoop;
0N/A }
0N/A FDBigInt halfUlp = constructPow52( B5, Ulp2 );
0N/A if ( (cmpResult = diff.cmp( halfUlp ) ) < 0 ){
0N/A // difference is small.
0N/A // this is close enough
0N/A if (mustSetRoundDir) {
0N/A roundDir = overvalue ? -1 : 1;
0N/A }
0N/A break correctionLoop;
0N/A } else if ( cmpResult == 0 ){
0N/A // difference is exactly half an ULP
0N/A // round to some other value maybe, then finish
0N/A dValue += 0.5*ulp( dValue, overvalue );
0N/A // should check for bigIntNBits == 1 here??
0N/A if (mustSetRoundDir) {
0N/A roundDir = overvalue ? -1 : 1;
0N/A }
0N/A break correctionLoop;
0N/A } else {
0N/A // difference is non-trivial.
0N/A // could scale addend by ratio of difference to
0N/A // halfUlp here, if we bothered to compute that difference.
0N/A // Most of the time ( I hope ) it is about 1 anyway.
0N/A dValue += ulp( dValue, overvalue );
0N/A if ( dValue == 0.0 || dValue == Double.POSITIVE_INFINITY )
0N/A break correctionLoop; // oops. Fell off end of range.
0N/A continue; // try again.
0N/A }
0N/A
0N/A }
0N/A return (isNegative)? -dValue : dValue;
0N/A }
0N/A }
0N/A
0N/A /*
0N/A * Take a FloatingDecimal, which we presumably just scanned in,
0N/A * and find out what its value is, as a float.
0N/A * This is distinct from doubleValue() to avoid the extremely
0N/A * unlikely case of a double rounding error, wherein the conversion
0N/A * to double has one rounding error, and the conversion of that double
0N/A * to a float has another rounding error, IN THE WRONG DIRECTION,
0N/A * ( because of the preference to a zero low-order bit ).
0N/A */
0N/A
4124N/A public strictfp float floatValue(){
0N/A int kDigits = Math.min( nDigits, singleMaxDecimalDigits+1 );
0N/A int iValue;
0N/A float fValue;
0N/A
0N/A // First, check for NaN and Infinity values
0N/A if(digits == infinity || digits == notANumber) {
0N/A if(digits == notANumber)
0N/A return Float.NaN;
0N/A else
0N/A return (isNegative?Float.NEGATIVE_INFINITY:Float.POSITIVE_INFINITY);
0N/A }
0N/A else {
0N/A /*
0N/A * convert the lead kDigits to an integer.
0N/A */
0N/A iValue = (int)digits[0]-(int)'0';
0N/A for ( int i=1; i < kDigits; i++ ){
0N/A iValue = iValue*10 + (int)digits[i]-(int)'0';
0N/A }
0N/A fValue = (float)iValue;
0N/A int exp = decExponent-kDigits;
0N/A /*
0N/A * iValue now contains an integer with the value of
0N/A * the first kDigits digits of the number.
0N/A * fValue contains the (float) of the same.
0N/A */
0N/A
0N/A if ( nDigits <= singleMaxDecimalDigits ){
0N/A /*
0N/A * possibly an easy case.
0N/A * We know that the digits can be represented
0N/A * exactly. And if the exponent isn't too outrageous,
0N/A * the whole thing can be done with one operation,
0N/A * thus one rounding error.
0N/A * Note that all our constructors trim all leading and
0N/A * trailing zeros, so simple values (including zero)
0N/A * will always end up here.
0N/A */
0N/A if (exp == 0 || fValue == 0.0f)
0N/A return (isNegative)? -fValue : fValue; // small floating integer
0N/A else if ( exp >= 0 ){
0N/A if ( exp <= singleMaxSmallTen ){
0N/A /*
0N/A * Can get the answer with one operation,
0N/A * thus one roundoff.
0N/A */
0N/A fValue *= singleSmall10pow[exp];
0N/A return (isNegative)? -fValue : fValue;
0N/A }
0N/A int slop = singleMaxDecimalDigits - kDigits;
0N/A if ( exp <= singleMaxSmallTen+slop ){
0N/A /*
0N/A * We can multiply dValue by 10^(slop)
0N/A * and it is still "small" and exact.
0N/A * Then we can multiply by 10^(exp-slop)
0N/A * with one rounding.
0N/A */
0N/A fValue *= singleSmall10pow[slop];
0N/A fValue *= singleSmall10pow[exp-slop];
0N/A return (isNegative)? -fValue : fValue;
0N/A }
0N/A /*
0N/A * Else we have a hard case with a positive exp.
0N/A */
0N/A } else {
0N/A if ( exp >= -singleMaxSmallTen ){
0N/A /*
0N/A * Can get the answer in one division.
0N/A */
0N/A fValue /= singleSmall10pow[-exp];
0N/A return (isNegative)? -fValue : fValue;
0N/A }
0N/A /*
0N/A * Else we have a hard case with a negative exp.
0N/A */
0N/A }
0N/A } else if ( (decExponent >= nDigits) && (nDigits+decExponent <= maxDecimalDigits) ){
0N/A /*
0N/A * In double-precision, this is an exact floating integer.
0N/A * So we can compute to double, then shorten to float
0N/A * with one round, and get the right answer.
0N/A *
0N/A * First, finish accumulating digits.
0N/A * Then convert that integer to a double, multiply
0N/A * by the appropriate power of ten, and convert to float.
0N/A */
0N/A long lValue = (long)iValue;
0N/A for ( int i=kDigits; i < nDigits; i++ ){
0N/A lValue = lValue*10L + (long)((int)digits[i]-(int)'0');
0N/A }
0N/A double dValue = (double)lValue;
0N/A exp = decExponent-nDigits;
0N/A dValue *= small10pow[exp];
0N/A fValue = (float)dValue;
0N/A return (isNegative)? -fValue : fValue;
0N/A
0N/A }
0N/A /*
0N/A * Harder cases:
0N/A * The sum of digits plus exponent is greater than
0N/A * what we think we can do with one error.
0N/A *
0N/A * Start by weeding out obviously out-of-range
0N/A * results, then convert to double and go to
0N/A * common hard-case code.
0N/A */
0N/A if ( decExponent > singleMaxDecimalExponent+1 ){
0N/A /*
0N/A * Lets face it. This is going to be
0N/A * Infinity. Cut to the chase.
0N/A */
0N/A return (isNegative)? Float.NEGATIVE_INFINITY : Float.POSITIVE_INFINITY;
0N/A } else if ( decExponent < singleMinDecimalExponent-1 ){
0N/A /*
0N/A * Lets face it. This is going to be
0N/A * zero. Cut to the chase.
0N/A */
0N/A return (isNegative)? -0.0f : 0.0f;
0N/A }
0N/A
0N/A /*
0N/A * Here, we do 'way too much work, but throwing away
0N/A * our partial results, and going and doing the whole
0N/A * thing as double, then throwing away half the bits that computes
0N/A * when we convert back to float.
0N/A *
0N/A * The alternative is to reproduce the whole multiple-precision
0N/A * algorithm for float precision, or to try to parameterize it
0N/A * for common usage. The former will take about 400 lines of code,
0N/A * and the latter I tried without success. Thus the semi-hack
0N/A * answer here.
0N/A */
0N/A mustSetRoundDir = !fromHex;
0N/A double dValue = doubleValue();
0N/A return stickyRound( dValue );
0N/A }
0N/A }
0N/A
0N/A
0N/A /*
0N/A * All the positive powers of 10 that can be
0N/A * represented exactly in double/float.
0N/A */
0N/A private static final double small10pow[] = {
0N/A 1.0e0,
0N/A 1.0e1, 1.0e2, 1.0e3, 1.0e4, 1.0e5,
0N/A 1.0e6, 1.0e7, 1.0e8, 1.0e9, 1.0e10,
0N/A 1.0e11, 1.0e12, 1.0e13, 1.0e14, 1.0e15,
0N/A 1.0e16, 1.0e17, 1.0e18, 1.0e19, 1.0e20,
0N/A 1.0e21, 1.0e22
0N/A };
0N/A
0N/A private static final float singleSmall10pow[] = {
0N/A 1.0e0f,
0N/A 1.0e1f, 1.0e2f, 1.0e3f, 1.0e4f, 1.0e5f,
0N/A 1.0e6f, 1.0e7f, 1.0e8f, 1.0e9f, 1.0e10f
0N/A };
0N/A
0N/A private static final double big10pow[] = {
0N/A 1e16, 1e32, 1e64, 1e128, 1e256 };
0N/A private static final double tiny10pow[] = {
0N/A 1e-16, 1e-32, 1e-64, 1e-128, 1e-256 };
0N/A
0N/A private static final int maxSmallTen = small10pow.length-1;
0N/A private static final int singleMaxSmallTen = singleSmall10pow.length-1;
0N/A
0N/A private static final int small5pow[] = {
0N/A 1,
0N/A 5,
0N/A 5*5,
0N/A 5*5*5,
0N/A 5*5*5*5,
0N/A 5*5*5*5*5,
0N/A 5*5*5*5*5*5,
0N/A 5*5*5*5*5*5*5,
0N/A 5*5*5*5*5*5*5*5,
0N/A 5*5*5*5*5*5*5*5*5,
0N/A 5*5*5*5*5*5*5*5*5*5,
0N/A 5*5*5*5*5*5*5*5*5*5*5,
0N/A 5*5*5*5*5*5*5*5*5*5*5*5,
0N/A 5*5*5*5*5*5*5*5*5*5*5*5*5
0N/A };
0N/A
0N/A
0N/A private static final long long5pow[] = {
0N/A 1L,
0N/A 5L,
0N/A 5L*5,
0N/A 5L*5*5,
0N/A 5L*5*5*5,
0N/A 5L*5*5*5*5,
0N/A 5L*5*5*5*5*5,
0N/A 5L*5*5*5*5*5*5,
0N/A 5L*5*5*5*5*5*5*5,
0N/A 5L*5*5*5*5*5*5*5*5,
0N/A 5L*5*5*5*5*5*5*5*5*5,
0N/A 5L*5*5*5*5*5*5*5*5*5*5,
0N/A 5L*5*5*5*5*5*5*5*5*5*5*5,
0N/A 5L*5*5*5*5*5*5*5*5*5*5*5*5,
0N/A 5L*5*5*5*5*5*5*5*5*5*5*5*5*5,
0N/A 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
0N/A 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
0N/A 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
0N/A 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
0N/A 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
0N/A 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
0N/A 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
0N/A 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
0N/A 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
0N/A 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
0N/A 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,
0N/A 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,
0N/A };
0N/A
0N/A // approximately ceil( log2( long5pow[i] ) )
0N/A private static final int n5bits[] = {
0N/A 0,
0N/A 3,
0N/A 5,
0N/A 7,
0N/A 10,
0N/A 12,
0N/A 14,
0N/A 17,
0N/A 19,
0N/A 21,
0N/A 24,
0N/A 26,
0N/A 28,
0N/A 31,
0N/A 33,
0N/A 35,
0N/A 38,
0N/A 40,
0N/A 42,
0N/A 45,
0N/A 47,
0N/A 49,
0N/A 52,
0N/A 54,
0N/A 56,
0N/A 59,
0N/A 61,
0N/A };
0N/A
0N/A private static final char infinity[] = { 'I', 'n', 'f', 'i', 'n', 'i', 't', 'y' };
0N/A private static final char notANumber[] = { 'N', 'a', 'N' };
0N/A private static final char zero[] = { '0', '0', '0', '0', '0', '0', '0', '0' };
0N/A
0N/A
0N/A /*
0N/A * Grammar is compatible with hexadecimal floating-point constants
0N/A * described in section 6.4.4.2 of the C99 specification.
0N/A */
926N/A private static Pattern hexFloatPattern = null;
926N/A private static synchronized Pattern getHexFloatPattern() {
926N/A if (hexFloatPattern == null) {
926N/A hexFloatPattern = Pattern.compile(
0N/A //1 234 56 7 8 9
0N/A "([-+])?0[xX](((\\p{XDigit}+)\\.?)|((\\p{XDigit}*)\\.(\\p{XDigit}+)))[pP]([-+])?(\\p{Digit}+)[fFdD]?"
0N/A );
926N/A }
926N/A return hexFloatPattern;
926N/A }
0N/A
0N/A /*
0N/A * Convert string s to a suitable floating decimal; uses the
0N/A * double constructor and set the roundDir variable appropriately
0N/A * in case the value is later converted to a float.
0N/A */
0N/A static FloatingDecimal parseHexString(String s) {
0N/A // Verify string is a member of the hexadecimal floating-point
0N/A // string language.
926N/A Matcher m = getHexFloatPattern().matcher(s);
0N/A boolean validInput = m.matches();
0N/A
0N/A if (!validInput) {
0N/A // Input does not match pattern
0N/A throw new NumberFormatException("For input string: \"" + s + "\"");
0N/A } else { // validInput
0N/A /*
0N/A * We must isolate the sign, significand, and exponent
0N/A * fields. The sign value is straightforward. Since
0N/A * floating-point numbers are stored with a normalized
0N/A * representation, the significand and exponent are
0N/A * interrelated.
0N/A *
0N/A * After extracting the sign, we normalized the
0N/A * significand as a hexadecimal value, calculating an
0N/A * exponent adjust for any shifts made during
0N/A * normalization. If the significand is zero, the
0N/A * exponent doesn't need to be examined since the output
0N/A * will be zero.
0N/A *
0N/A * Next the exponent in the input string is extracted.
0N/A * Afterwards, the significand is normalized as a *binary*
0N/A * value and the input value's normalized exponent can be
0N/A * computed. The significand bits are copied into a
0N/A * double significand; if the string has more logical bits
0N/A * than can fit in a double, the extra bits affect the
0N/A * round and sticky bits which are used to round the final
0N/A * value.
0N/A */
0N/A
0N/A // Extract significand sign
0N/A String group1 = m.group(1);
0N/A double sign = (( group1 == null ) || group1.equals("+"))? 1.0 : -1.0;
0N/A
0N/A
0N/A // Extract Significand magnitude
0N/A /*
0N/A * Based on the form of the significand, calculate how the
0N/A * binary exponent needs to be adjusted to create a
0N/A * normalized *hexadecimal* floating-point number; that
0N/A * is, a number where there is one nonzero hex digit to
0N/A * the left of the (hexa)decimal point. Since we are
0N/A * adjusting a binary, not hexadecimal exponent, the
0N/A * exponent is adjusted by a multiple of 4.
0N/A *
0N/A * There are a number of significand scenarios to consider;
0N/A * letters are used in indicate nonzero digits:
0N/A *
0N/A * 1. 000xxxx => x.xxx normalized
0N/A * increase exponent by (number of x's - 1)*4
0N/A *
0N/A * 2. 000xxx.yyyy => x.xxyyyy normalized
0N/A * increase exponent by (number of x's - 1)*4
0N/A *
0N/A * 3. .000yyy => y.yy normalized
0N/A * decrease exponent by (number of zeros + 1)*4
0N/A *
0N/A * 4. 000.00000yyy => y.yy normalized
0N/A * decrease exponent by (number of zeros to right of point + 1)*4
0N/A *
0N/A * If the significand is exactly zero, return a properly
0N/A * signed zero.
0N/A */
0N/A
0N/A String significandString =null;
0N/A int signifLength = 0;
0N/A int exponentAdjust = 0;
0N/A {
0N/A int leftDigits = 0; // number of meaningful digits to
0N/A // left of "decimal" point
0N/A // (leading zeros stripped)
0N/A int rightDigits = 0; // number of digits to right of
0N/A // "decimal" point; leading zeros
0N/A // must always be accounted for
0N/A /*
0N/A * The significand is made up of either
0N/A *
0N/A * 1. group 4 entirely (integer portion only)
0N/A *
0N/A * OR
0N/A *
0N/A * 2. the fractional portion from group 7 plus any
0N/A * (optional) integer portions from group 6.
0N/A */
0N/A String group4;
0N/A if( (group4 = m.group(4)) != null) { // Integer-only significand
0N/A // Leading zeros never matter on the integer portion
0N/A significandString = stripLeadingZeros(group4);
0N/A leftDigits = significandString.length();
0N/A }
0N/A else {
0N/A // Group 6 is the optional integer; leading zeros
0N/A // never matter on the integer portion
0N/A String group6 = stripLeadingZeros(m.group(6));
0N/A leftDigits = group6.length();
0N/A
0N/A // fraction
0N/A String group7 = m.group(7);
0N/A rightDigits = group7.length();
0N/A
0N/A // Turn "integer.fraction" into "integer"+"fraction"
0N/A significandString =
0N/A ((group6 == null)?"":group6) + // is the null
0N/A // check necessary?
0N/A group7;
0N/A }
0N/A
0N/A significandString = stripLeadingZeros(significandString);
0N/A signifLength = significandString.length();
0N/A
0N/A /*
0N/A * Adjust exponent as described above
0N/A */
0N/A if (leftDigits >= 1) { // Cases 1 and 2
0N/A exponentAdjust = 4*(leftDigits - 1);
0N/A } else { // Cases 3 and 4
0N/A exponentAdjust = -4*( rightDigits - signifLength + 1);
0N/A }
0N/A
0N/A // If the significand is zero, the exponent doesn't
0N/A // matter; return a properly signed zero.
0N/A
0N/A if (signifLength == 0) { // Only zeros in input
0N/A return new FloatingDecimal(sign * 0.0);
0N/A }
0N/A }
0N/A
0N/A // Extract Exponent
0N/A /*
0N/A * Use an int to read in the exponent value; this should
0N/A * provide more than sufficient range for non-contrived
0N/A * inputs. If reading the exponent in as an int does
0N/A * overflow, examine the sign of the exponent and
0N/A * significand to determine what to do.
0N/A */
0N/A String group8 = m.group(8);
0N/A boolean positiveExponent = ( group8 == null ) || group8.equals("+");
0N/A long unsignedRawExponent;
0N/A try {
0N/A unsignedRawExponent = Integer.parseInt(m.group(9));
0N/A }
0N/A catch (NumberFormatException e) {
0N/A // At this point, we know the exponent is
0N/A // syntactically well-formed as a sequence of
0N/A // digits. Therefore, if an NumberFormatException
0N/A // is thrown, it must be due to overflowing int's
0N/A // range. Also, at this point, we have already
0N/A // checked for a zero significand. Thus the signs
0N/A // of the exponent and significand determine the
0N/A // final result:
0N/A //
0N/A // significand
0N/A // + -
0N/A // exponent + +infinity -infinity
0N/A // - +0.0 -0.0
0N/A return new FloatingDecimal(sign * (positiveExponent ?
0N/A Double.POSITIVE_INFINITY : 0.0));
0N/A }
0N/A
0N/A long rawExponent =
0N/A (positiveExponent ? 1L : -1L) * // exponent sign
0N/A unsignedRawExponent; // exponent magnitude
0N/A
0N/A // Calculate partially adjusted exponent
0N/A long exponent = rawExponent + exponentAdjust ;
0N/A
0N/A // Starting copying non-zero bits into proper position in
0N/A // a long; copy explicit bit too; this will be masked
0N/A // later for normal values.
0N/A
0N/A boolean round = false;
0N/A boolean sticky = false;
0N/A int bitsCopied=0;
0N/A int nextShift=0;
0N/A long significand=0L;
0N/A // First iteration is different, since we only copy
0N/A // from the leading significand bit; one more exponent
0N/A // adjust will be needed...
0N/A
0N/A // IMPORTANT: make leadingDigit a long to avoid
0N/A // surprising shift semantics!
0N/A long leadingDigit = getHexDigit(significandString, 0);
0N/A
0N/A /*
0N/A * Left shift the leading digit (53 - (bit position of
0N/A * leading 1 in digit)); this sets the top bit of the
0N/A * significand to 1. The nextShift value is adjusted
0N/A * to take into account the number of bit positions of
0N/A * the leadingDigit actually used. Finally, the
0N/A * exponent is adjusted to normalize the significand
0N/A * as a binary value, not just a hex value.
0N/A */
0N/A if (leadingDigit == 1) {
0N/A significand |= leadingDigit << 52;
0N/A nextShift = 52 - 4;
0N/A /* exponent += 0 */ }
0N/A else if (leadingDigit <= 3) { // [2, 3]
0N/A significand |= leadingDigit << 51;
0N/A nextShift = 52 - 5;
0N/A exponent += 1;
0N/A }
0N/A else if (leadingDigit <= 7) { // [4, 7]
0N/A significand |= leadingDigit << 50;
0N/A nextShift = 52 - 6;
0N/A exponent += 2;
0N/A }
0N/A else if (leadingDigit <= 15) { // [8, f]
0N/A significand |= leadingDigit << 49;
0N/A nextShift = 52 - 7;
0N/A exponent += 3;
0N/A } else {
0N/A throw new AssertionError("Result from digit conversion too large!");
0N/A }
0N/A // The preceding if-else could be replaced by a single
0N/A // code block based on the high-order bit set in
0N/A // leadingDigit. Given leadingOnePosition,
0N/A
0N/A // significand |= leadingDigit << (SIGNIFICAND_WIDTH - leadingOnePosition);
0N/A // nextShift = 52 - (3 + leadingOnePosition);
0N/A // exponent += (leadingOnePosition-1);
0N/A
0N/A
0N/A /*
0N/A * Now the exponent variable is equal to the normalized
0N/A * binary exponent. Code below will make representation
0N/A * adjustments if the exponent is incremented after
0N/A * rounding (includes overflows to infinity) or if the
0N/A * result is subnormal.
0N/A */
0N/A
0N/A // Copy digit into significand until the significand can't
0N/A // hold another full hex digit or there are no more input
0N/A // hex digits.
0N/A int i = 0;
0N/A for(i = 1;
0N/A i < signifLength && nextShift >= 0;
0N/A i++) {
0N/A long currentDigit = getHexDigit(significandString, i);
0N/A significand |= (currentDigit << nextShift);
0N/A nextShift-=4;
0N/A }
0N/A
0N/A // After the above loop, the bulk of the string is copied.
0N/A // Now, we must copy any partial hex digits into the
0N/A // significand AND compute the round bit and start computing
0N/A // sticky bit.
0N/A
0N/A if ( i < signifLength ) { // at least one hex input digit exists
0N/A long currentDigit = getHexDigit(significandString, i);
0N/A
0N/A // from nextShift, figure out how many bits need
0N/A // to be copied, if any
0N/A switch(nextShift) { // must be negative
0N/A case -1:
0N/A // three bits need to be copied in; can
0N/A // set round bit
0N/A significand |= ((currentDigit & 0xEL) >> 1);
0N/A round = (currentDigit & 0x1L) != 0L;
0N/A break;
0N/A
0N/A case -2:
0N/A // two bits need to be copied in; can
0N/A // set round and start sticky
0N/A significand |= ((currentDigit & 0xCL) >> 2);
0N/A round = (currentDigit &0x2L) != 0L;
0N/A sticky = (currentDigit & 0x1L) != 0;
0N/A break;
0N/A
0N/A case -3:
0N/A // one bit needs to be copied in
0N/A significand |= ((currentDigit & 0x8L)>>3);
0N/A // Now set round and start sticky, if possible
0N/A round = (currentDigit &0x4L) != 0L;
0N/A sticky = (currentDigit & 0x3L) != 0;
0N/A break;
0N/A
0N/A case -4:
0N/A // all bits copied into significand; set
0N/A // round and start sticky
0N/A round = ((currentDigit & 0x8L) != 0); // is top bit set?
0N/A // nonzeros in three low order bits?
0N/A sticky = (currentDigit & 0x7L) != 0;
0N/A break;
0N/A
0N/A default:
0N/A throw new AssertionError("Unexpected shift distance remainder.");
0N/A // break;
0N/A }
0N/A
0N/A // Round is set; sticky might be set.
0N/A
0N/A // For the sticky bit, it suffices to check the
0N/A // current digit and test for any nonzero digits in
0N/A // the remaining unprocessed input.
0N/A i++;
0N/A while(i < signifLength && !sticky) {
0N/A currentDigit = getHexDigit(significandString,i);
0N/A sticky = sticky || (currentDigit != 0);
0N/A i++;
0N/A }
0N/A
0N/A }
0N/A // else all of string was seen, round and sticky are
0N/A // correct as false.
0N/A
0N/A
0N/A // Check for overflow and update exponent accordingly.
0N/A
0N/A if (exponent > DoubleConsts.MAX_EXPONENT) { // Infinite result
0N/A // overflow to properly signed infinity
0N/A return new FloatingDecimal(sign * Double.POSITIVE_INFINITY);
0N/A } else { // Finite return value
0N/A if (exponent <= DoubleConsts.MAX_EXPONENT && // (Usually) normal result
0N/A exponent >= DoubleConsts.MIN_EXPONENT) {
0N/A
0N/A // The result returned in this block cannot be a
0N/A // zero or subnormal; however after the
0N/A // significand is adjusted from rounding, we could
0N/A // still overflow in infinity.
0N/A
0N/A // AND exponent bits into significand; if the
0N/A // significand is incremented and overflows from
0N/A // rounding, this combination will update the
0N/A // exponent correctly, even in the case of
0N/A // Double.MAX_VALUE overflowing to infinity.
0N/A
0N/A significand = (( ((long)exponent +
0N/A (long)DoubleConsts.EXP_BIAS) <<
0N/A (DoubleConsts.SIGNIFICAND_WIDTH-1))
0N/A & DoubleConsts.EXP_BIT_MASK) |
0N/A (DoubleConsts.SIGNIF_BIT_MASK & significand);
0N/A
0N/A } else { // Subnormal or zero
0N/A // (exponent < DoubleConsts.MIN_EXPONENT)
0N/A
0N/A if (exponent < (DoubleConsts.MIN_SUB_EXPONENT -1 )) {
0N/A // No way to round back to nonzero value
0N/A // regardless of significand if the exponent is
0N/A // less than -1075.
0N/A return new FloatingDecimal(sign * 0.0);
0N/A } else { // -1075 <= exponent <= MIN_EXPONENT -1 = -1023
0N/A /*
0N/A * Find bit position to round to; recompute
0N/A * round and sticky bits, and shift
0N/A * significand right appropriately.
0N/A */
0N/A
0N/A sticky = sticky || round;
0N/A round = false;
0N/A
0N/A // Number of bits of significand to preserve is
0N/A // exponent - abs_min_exp +1
0N/A // check:
0N/A // -1075 +1074 + 1 = 0
0N/A // -1023 +1074 + 1 = 52
0N/A
0N/A int bitsDiscarded = 53 -
0N/A ((int)exponent - DoubleConsts.MIN_SUB_EXPONENT + 1);
0N/A assert bitsDiscarded >= 1 && bitsDiscarded <= 53;
0N/A
0N/A // What to do here:
0N/A // First, isolate the new round bit
0N/A round = (significand & (1L << (bitsDiscarded -1))) != 0L;
0N/A if (bitsDiscarded > 1) {
0N/A // create mask to update sticky bits; low
0N/A // order bitsDiscarded bits should be 1
0N/A long mask = ~((~0L) << (bitsDiscarded -1));
0N/A sticky = sticky || ((significand & mask) != 0L ) ;
0N/A }
0N/A
0N/A // Now, discard the bits
0N/A significand = significand >> bitsDiscarded;
0N/A
0N/A significand = (( ((long)(DoubleConsts.MIN_EXPONENT -1) + // subnorm exp.
0N/A (long)DoubleConsts.EXP_BIAS) <<
0N/A (DoubleConsts.SIGNIFICAND_WIDTH-1))
0N/A & DoubleConsts.EXP_BIT_MASK) |
0N/A (DoubleConsts.SIGNIF_BIT_MASK & significand);
0N/A }
0N/A }
0N/A
0N/A // The significand variable now contains the currently
0N/A // appropriate exponent bits too.
0N/A
0N/A /*
0N/A * Determine if significand should be incremented;
0N/A * making this determination depends on the least
0N/A * significant bit and the round and sticky bits.
0N/A *
0N/A * Round to nearest even rounding table, adapted from
0N/A * table 4.7 in "Computer Arithmetic" by IsraelKoren.
0N/A * The digit to the left of the "decimal" point is the
0N/A * least significant bit, the digits to the right of
0N/A * the point are the round and sticky bits
0N/A *
0N/A * Number Round(x)
0N/A * x0.00 x0.
0N/A * x0.01 x0.
0N/A * x0.10 x0.
0N/A * x0.11 x1. = x0. +1
0N/A * x1.00 x1.
0N/A * x1.01 x1.
0N/A * x1.10 x1. + 1
0N/A * x1.11 x1. + 1
0N/A */
0N/A boolean incremented = false;
0N/A boolean leastZero = ((significand & 1L) == 0L);
0N/A if( ( leastZero && round && sticky ) ||
0N/A ((!leastZero) && round )) {
0N/A incremented = true;
0N/A significand++;
0N/A }
0N/A
0N/A FloatingDecimal fd = new FloatingDecimal(FpUtils.rawCopySign(
0N/A Double.longBitsToDouble(significand),
0N/A sign));
0N/A
0N/A /*
0N/A * Set roundingDir variable field of fd properly so
0N/A * that the input string can be properly rounded to a
0N/A * float value. There are two cases to consider:
0N/A *
0N/A * 1. rounding to double discards sticky bit
0N/A * information that would change the result of a float
0N/A * rounding (near halfway case between two floats)
0N/A *
0N/A * 2. rounding to double rounds up when rounding up
0N/A * would not occur when rounding to float.
0N/A *
0N/A * For former case only needs to be considered when
0N/A * the bits rounded away when casting to float are all
0N/A * zero; otherwise, float round bit is properly set
0N/A * and sticky will already be true.
0N/A *
0N/A * The lower exponent bound for the code below is the
0N/A * minimum (normalized) subnormal exponent - 1 since a
0N/A * value with that exponent can round up to the
0N/A * minimum subnormal value and the sticky bit
0N/A * information must be preserved (i.e. case 1).
0N/A */
0N/A if ((exponent >= FloatConsts.MIN_SUB_EXPONENT-1) &&
0N/A (exponent <= FloatConsts.MAX_EXPONENT ) ){
0N/A // Outside above exponent range, the float value
0N/A // will be zero or infinity.
0N/A
0N/A /*
0N/A * If the low-order 28 bits of a rounded double
0N/A * significand are 0, the double could be a
0N/A * half-way case for a rounding to float. If the
0N/A * double value is a half-way case, the double
0N/A * significand may have to be modified to round
0N/A * the the right float value (see the stickyRound
0N/A * method). If the rounding to double has lost
0N/A * what would be float sticky bit information, the
0N/A * double significand must be incremented. If the
0N/A * double value's significand was itself
0N/A * incremented, the float value may end up too
0N/A * large so the increment should be undone.
0N/A */
0N/A if ((significand & 0xfffffffL) == 0x0L) {
0N/A // For negative values, the sign of the
0N/A // roundDir is the same as for positive values
0N/A // since adding 1 increasing the significand's
0N/A // magnitude and subtracting 1 decreases the
0N/A // significand's magnitude. If neither round
0N/A // nor sticky is true, the double value is
0N/A // exact and no adjustment is required for a
0N/A // proper float rounding.
0N/A if( round || sticky) {
0N/A if (leastZero) { // prerounding lsb is 0
0N/A // If round and sticky were both true,
0N/A // and the least significant
0N/A // significand bit were 0, the rounded
0N/A // significand would not have its
0N/A // low-order bits be zero. Therefore,
0N/A // we only need to adjust the
0N/A // significand if round XOR sticky is
0N/A // true.
0N/A if (round ^ sticky) {
0N/A fd.roundDir = 1;
0N/A }
0N/A }
0N/A else { // prerounding lsb is 1
0N/A // If the prerounding lsb is 1 and the
0N/A // resulting significand has its
0N/A // low-order bits zero, the significand
0N/A // was incremented. Here, we undo the
0N/A // increment, which will ensure the
0N/A // right guard and sticky bits for the
0N/A // float rounding.
0N/A if (round)
0N/A fd.roundDir = -1;
0N/A }
0N/A }
0N/A }
0N/A }
0N/A
0N/A fd.fromHex = true;
0N/A return fd;
0N/A }
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Return <code>s</code> with any leading zeros removed.
0N/A */
0N/A static String stripLeadingZeros(String s) {
0N/A return s.replaceFirst("^0+", "");
0N/A }
0N/A
0N/A /**
0N/A * Extract a hexadecimal digit from position <code>position</code>
0N/A * of string <code>s</code>.
0N/A */
0N/A static int getHexDigit(String s, int position) {
0N/A int value = Character.digit(s.charAt(position), 16);
0N/A if (value <= -1 || value >= 16) {
0N/A throw new AssertionError("Unexpected failure of digit conversion of " +
0N/A s.charAt(position));
0N/A }
0N/A return value;
0N/A }
0N/A
0N/A
0N/A}
0N/A
0N/A/*
0N/A * A really, really simple bigint package
0N/A * tailored to the needs of floating base conversion.
0N/A */
0N/Aclass FDBigInt {
0N/A int nWords; // number of words used
0N/A int data[]; // value: data[0] is least significant
0N/A
0N/A
0N/A public FDBigInt( int v ){
0N/A nWords = 1;
0N/A data = new int[1];
0N/A data[0] = v;
0N/A }
0N/A
0N/A public FDBigInt( long v ){
0N/A data = new int[2];
0N/A data[0] = (int)v;
0N/A data[1] = (int)(v>>>32);
0N/A nWords = (data[1]==0) ? 1 : 2;
0N/A }
0N/A
0N/A public FDBigInt( FDBigInt other ){
0N/A data = new int[nWords = other.nWords];
0N/A System.arraycopy( other.data, 0, data, 0, nWords );
0N/A }
0N/A
0N/A private FDBigInt( int [] d, int n ){
0N/A data = d;
0N/A nWords = n;
0N/A }
0N/A
0N/A public FDBigInt( long seed, char digit[], int nd0, int nd ){
0N/A int n= (nd+8)/9; // estimate size needed.
0N/A if ( n < 2 ) n = 2;
0N/A data = new int[n]; // allocate enough space
0N/A data[0] = (int)seed; // starting value
0N/A data[1] = (int)(seed>>>32);
0N/A nWords = (data[1]==0) ? 1 : 2;
0N/A int i = nd0;
0N/A int limit = nd-5; // slurp digits 5 at a time.
0N/A int v;
0N/A while ( i < limit ){
0N/A int ilim = i+5;
0N/A v = (int)digit[i++]-(int)'0';
0N/A while( i <ilim ){
0N/A v = 10*v + (int)digit[i++]-(int)'0';
0N/A }
0N/A multaddMe( 100000, v); // ... where 100000 is 10^5.
0N/A }
0N/A int factor = 1;
0N/A v = 0;
0N/A while ( i < nd ){
0N/A v = 10*v + (int)digit[i++]-(int)'0';
0N/A factor *= 10;
0N/A }
0N/A if ( factor != 1 ){
0N/A multaddMe( factor, v );
0N/A }
0N/A }
0N/A
0N/A /*
0N/A * Left shift by c bits.
0N/A * Shifts this in place.
0N/A */
0N/A public void
0N/A lshiftMe( int c )throws IllegalArgumentException {
0N/A if ( c <= 0 ){
0N/A if ( c == 0 )
0N/A return; // silly.
0N/A else
0N/A throw new IllegalArgumentException("negative shift count");
0N/A }
0N/A int wordcount = c>>5;
0N/A int bitcount = c & 0x1f;
0N/A int anticount = 32-bitcount;
0N/A int t[] = data;
0N/A int s[] = data;
0N/A if ( nWords+wordcount+1 > t.length ){
0N/A // reallocate.
0N/A t = new int[ nWords+wordcount+1 ];
0N/A }
0N/A int target = nWords+wordcount;
0N/A int src = nWords-1;
0N/A if ( bitcount == 0 ){
0N/A // special hack, since an anticount of 32 won't go!
0N/A System.arraycopy( s, 0, t, wordcount, nWords );
0N/A target = wordcount-1;
0N/A } else {
0N/A t[target--] = s[src]>>>anticount;
0N/A while ( src >= 1 ){
0N/A t[target--] = (s[src]<<bitcount) | (s[--src]>>>anticount);
0N/A }
0N/A t[target--] = s[src]<<bitcount;
0N/A }
0N/A while( target >= 0 ){
0N/A t[target--] = 0;
0N/A }
0N/A data = t;
0N/A nWords += wordcount + 1;
0N/A // may have constructed high-order word of 0.
0N/A // if so, trim it
0N/A while ( nWords > 1 && data[nWords-1] == 0 )
0N/A nWords--;
0N/A }
0N/A
0N/A /*
0N/A * normalize this number by shifting until
0N/A * the MSB of the number is at 0x08000000.
0N/A * This is in preparation for quoRemIteration, below.
0N/A * The idea is that, to make division easier, we want the
0N/A * divisor to be "normalized" -- usually this means shifting
0N/A * the MSB into the high words sign bit. But because we know that
0N/A * the quotient will be 0 < q < 10, we would like to arrange that
0N/A * the dividend not span up into another word of precision.
0N/A * (This needs to be explained more clearly!)
0N/A */
0N/A public int
0N/A normalizeMe() throws IllegalArgumentException {
0N/A int src;
0N/A int wordcount = 0;
0N/A int bitcount = 0;
0N/A int v = 0;
0N/A for ( src= nWords-1 ; src >= 0 && (v=data[src]) == 0 ; src--){
0N/A wordcount += 1;
0N/A }
0N/A if ( src < 0 ){
0N/A // oops. Value is zero. Cannot normalize it!
0N/A throw new IllegalArgumentException("zero value");
0N/A }
0N/A /*
0N/A * In most cases, we assume that wordcount is zero. This only
0N/A * makes sense, as we try not to maintain any high-order
0N/A * words full of zeros. In fact, if there are zeros, we will
0N/A * simply SHORTEN our number at this point. Watch closely...
0N/A */
0N/A nWords -= wordcount;
0N/A /*
0N/A * Compute how far left we have to shift v s.t. its highest-
0N/A * order bit is in the right place. Then call lshiftMe to
0N/A * do the work.
0N/A */
0N/A if ( (v & 0xf0000000) != 0 ){
0N/A // will have to shift up into the next word.
0N/A // too bad.
0N/A for( bitcount = 32 ; (v & 0xf0000000) != 0 ; bitcount-- )
0N/A v >>>= 1;
0N/A } else {
0N/A while ( v <= 0x000fffff ){
0N/A // hack: byte-at-a-time shifting
0N/A v <<= 8;
0N/A bitcount += 8;
0N/A }
0N/A while ( v <= 0x07ffffff ){
0N/A v <<= 1;
0N/A bitcount += 1;
0N/A }
0N/A }
0N/A if ( bitcount != 0 )
0N/A lshiftMe( bitcount );
0N/A return bitcount;
0N/A }
0N/A
0N/A /*
0N/A * Multiply a FDBigInt by an int.
0N/A * Result is a new FDBigInt.
0N/A */
0N/A public FDBigInt
0N/A mult( int iv ) {
0N/A long v = iv;
0N/A int r[];
0N/A long p;
0N/A
0N/A // guess adequate size of r.
0N/A r = new int[ ( v * ((long)data[nWords-1]&0xffffffffL) > 0xfffffffL ) ? nWords+1 : nWords ];
0N/A p = 0L;
0N/A for( int i=0; i < nWords; i++ ) {
0N/A p += v * ((long)data[i]&0xffffffffL);
0N/A r[i] = (int)p;
0N/A p >>>= 32;
0N/A }
0N/A if ( p == 0L){
0N/A return new FDBigInt( r, nWords );
0N/A } else {
0N/A r[nWords] = (int)p;
0N/A return new FDBigInt( r, nWords+1 );
0N/A }
0N/A }
0N/A
0N/A /*
0N/A * Multiply a FDBigInt by an int and add another int.
0N/A * Result is computed in place.
0N/A * Hope it fits!
0N/A */
0N/A public void
0N/A multaddMe( int iv, int addend ) {
0N/A long v = iv;
0N/A long p;
0N/A
0N/A // unroll 0th iteration, doing addition.
0N/A p = v * ((long)data[0]&0xffffffffL) + ((long)addend&0xffffffffL);
0N/A data[0] = (int)p;
0N/A p >>>= 32;
0N/A for( int i=1; i < nWords; i++ ) {
0N/A p += v * ((long)data[i]&0xffffffffL);
0N/A data[i] = (int)p;
0N/A p >>>= 32;
0N/A }
0N/A if ( p != 0L){
0N/A data[nWords] = (int)p; // will fail noisily if illegal!
0N/A nWords++;
0N/A }
0N/A }
0N/A
0N/A /*
0N/A * Multiply a FDBigInt by another FDBigInt.
0N/A * Result is a new FDBigInt.
0N/A */
0N/A public FDBigInt
0N/A mult( FDBigInt other ){
0N/A // crudely guess adequate size for r
0N/A int r[] = new int[ nWords + other.nWords ];
0N/A int i;
0N/A // I think I am promised zeros...
0N/A
0N/A for( i = 0; i < this.nWords; i++ ){
0N/A long v = (long)this.data[i] & 0xffffffffL; // UNSIGNED CONVERSION
0N/A long p = 0L;
0N/A int j;
0N/A for( j = 0; j < other.nWords; j++ ){
0N/A p += ((long)r[i+j]&0xffffffffL) + v*((long)other.data[j]&0xffffffffL); // UNSIGNED CONVERSIONS ALL 'ROUND.
0N/A r[i+j] = (int)p;
0N/A p >>>= 32;
0N/A }
0N/A r[i+j] = (int)p;
0N/A }
0N/A // compute how much of r we actually needed for all that.
0N/A for ( i = r.length-1; i> 0; i--)
0N/A if ( r[i] != 0 )
0N/A break;
0N/A return new FDBigInt( r, i+1 );
0N/A }
0N/A
0N/A /*
0N/A * Add one FDBigInt to another. Return a FDBigInt
0N/A */
0N/A public FDBigInt
0N/A add( FDBigInt other ){
0N/A int i;
0N/A int a[], b[];
0N/A int n, m;
0N/A long c = 0L;
0N/A // arrange such that a.nWords >= b.nWords;
0N/A // n = a.nWords, m = b.nWords
0N/A if ( this.nWords >= other.nWords ){
0N/A a = this.data;
0N/A n = this.nWords;
0N/A b = other.data;
0N/A m = other.nWords;
0N/A } else {
0N/A a = other.data;
0N/A n = other.nWords;
0N/A b = this.data;
0N/A m = this.nWords;
0N/A }
0N/A int r[] = new int[ n ];
0N/A for ( i = 0; i < n; i++ ){
0N/A c += (long)a[i] & 0xffffffffL;
0N/A if ( i < m ){
0N/A c += (long)b[i] & 0xffffffffL;
0N/A }
0N/A r[i] = (int) c;
0N/A c >>= 32; // signed shift.
0N/A }
0N/A if ( c != 0L ){
0N/A // oops -- carry out -- need longer result.
0N/A int s[] = new int[ r.length+1 ];
0N/A System.arraycopy( r, 0, s, 0, r.length );
0N/A s[i++] = (int)c;
0N/A return new FDBigInt( s, i );
0N/A }
0N/A return new FDBigInt( r, i );
0N/A }
0N/A
0N/A /*
0N/A * Subtract one FDBigInt from another. Return a FDBigInt
0N/A * Assert that the result is positive.
0N/A */
0N/A public FDBigInt
0N/A sub( FDBigInt other ){
0N/A int r[] = new int[ this.nWords ];
0N/A int i;
0N/A int n = this.nWords;
0N/A int m = other.nWords;
0N/A int nzeros = 0;
0N/A long c = 0L;
0N/A for ( i = 0; i < n; i++ ){
0N/A c += (long)this.data[i] & 0xffffffffL;
0N/A if ( i < m ){
0N/A c -= (long)other.data[i] & 0xffffffffL;
0N/A }
0N/A if ( ( r[i] = (int) c ) == 0 )
0N/A nzeros++;
0N/A else
0N/A nzeros = 0;
0N/A c >>= 32; // signed shift
0N/A }
0N/A assert c == 0L : c; // borrow out of subtract
0N/A assert dataInRangeIsZero(i, m, other); // negative result of subtract
0N/A return new FDBigInt( r, n-nzeros );
0N/A }
0N/A
0N/A private static boolean dataInRangeIsZero(int i, int m, FDBigInt other) {
0N/A while ( i < m )
0N/A if (other.data[i++] != 0)
0N/A return false;
0N/A return true;
0N/A }
0N/A
0N/A /*
0N/A * Compare FDBigInt with another FDBigInt. Return an integer
0N/A * >0: this > other
0N/A * 0: this == other
0N/A * <0: this < other
0N/A */
0N/A public int
0N/A cmp( FDBigInt other ){
0N/A int i;
0N/A if ( this.nWords > other.nWords ){
0N/A // if any of my high-order words is non-zero,
0N/A // then the answer is evident
0N/A int j = other.nWords-1;
0N/A for ( i = this.nWords-1; i > j ; i-- )
0N/A if ( this.data[i] != 0 ) return 1;
0N/A }else if ( this.nWords < other.nWords ){
0N/A // if any of other's high-order words is non-zero,
0N/A // then the answer is evident
0N/A int j = this.nWords-1;
0N/A for ( i = other.nWords-1; i > j ; i-- )
0N/A if ( other.data[i] != 0 ) return -1;
0N/A } else{
0N/A i = this.nWords-1;
0N/A }
0N/A for ( ; i > 0 ; i-- )
0N/A if ( this.data[i] != other.data[i] )
0N/A break;
0N/A // careful! want unsigned compare!
0N/A // use brute force here.
0N/A int a = this.data[i];
0N/A int b = other.data[i];
0N/A if ( a < 0 ){
0N/A // a is really big, unsigned
0N/A if ( b < 0 ){
0N/A return a-b; // both big, negative
0N/A } else {
0N/A return 1; // b not big, answer is obvious;
0N/A }
0N/A } else {
0N/A // a is not really big
0N/A if ( b < 0 ) {
0N/A // but b is really big
0N/A return -1;
0N/A } else {
0N/A return a - b;
0N/A }
0N/A }
0N/A }
0N/A
0N/A /*
0N/A * Compute
0N/A * q = (int)( this / S )
0N/A * this = 10 * ( this mod S )
0N/A * Return q.
0N/A * This is the iteration step of digit development for output.
0N/A * We assume that S has been normalized, as above, and that
0N/A * "this" has been lshift'ed accordingly.
0N/A * Also assume, of course, that the result, q, can be expressed
0N/A * as an integer, 0 <= q < 10.
0N/A */
0N/A public int
0N/A quoRemIteration( FDBigInt S )throws IllegalArgumentException {
0N/A // ensure that this and S have the same number of
0N/A // digits. If S is properly normalized and q < 10 then
0N/A // this must be so.
0N/A if ( nWords != S.nWords ){
0N/A throw new IllegalArgumentException("disparate values");
0N/A }
0N/A // estimate q the obvious way. We will usually be
0N/A // right. If not, then we're only off by a little and
0N/A // will re-add.
0N/A int n = nWords-1;
0N/A long q = ((long)data[n]&0xffffffffL) / (long)S.data[n];
0N/A long diff = 0L;
0N/A for ( int i = 0; i <= n ; i++ ){
0N/A diff += ((long)data[i]&0xffffffffL) - q*((long)S.data[i]&0xffffffffL);
0N/A data[i] = (int)diff;
0N/A diff >>= 32; // N.B. SIGNED shift.
0N/A }
0N/A if ( diff != 0L ) {
0N/A // damn, damn, damn. q is too big.
0N/A // add S back in until this turns +. This should
0N/A // not be very many times!
0N/A long sum = 0L;
0N/A while ( sum == 0L ){
0N/A sum = 0L;
0N/A for ( int i = 0; i <= n; i++ ){
0N/A sum += ((long)data[i]&0xffffffffL) + ((long)S.data[i]&0xffffffffL);
0N/A data[i] = (int) sum;
0N/A sum >>= 32; // Signed or unsigned, answer is 0 or 1
0N/A }
0N/A /*
0N/A * Originally the following line read
0N/A * "if ( sum !=0 && sum != -1 )"
0N/A * but that would be wrong, because of the
0N/A * treatment of the two values as entirely unsigned,
0N/A * it would be impossible for a carry-out to be interpreted
0N/A * as -1 -- it would have to be a single-bit carry-out, or
0N/A * +1.
0N/A */
0N/A assert sum == 0 || sum == 1 : sum; // carry out of division correction
0N/A q -= 1;
0N/A }
0N/A }
0N/A // finally, we can multiply this by 10.
0N/A // it cannot overflow, right, as the high-order word has
0N/A // at least 4 high-order zeros!
0N/A long p = 0L;
0N/A for ( int i = 0; i <= n; i++ ){
0N/A p += 10*((long)data[i]&0xffffffffL);
0N/A data[i] = (int)p;
0N/A p >>= 32; // SIGNED shift.
0N/A }
0N/A assert p == 0L : p; // Carry out of *10
0N/A return (int)q;
0N/A }
0N/A
0N/A public long
0N/A longValue(){
0N/A // if this can be represented as a long, return the value
0N/A assert this.nWords > 0 : this.nWords; // longValue confused
0N/A
0N/A if (this.nWords == 1)
0N/A return ((long)data[0]&0xffffffffL);
0N/A
0N/A assert dataInRangeIsZero(2, this.nWords, this); // value too big
0N/A assert data[1] >= 0; // value too big
0N/A return ((long)(data[1]) << 32) | ((long)data[0]&0xffffffffL);
0N/A }
0N/A
0N/A public String
0N/A toString() {
0N/A StringBuffer r = new StringBuffer(30);
0N/A r.append('[');
0N/A int i = Math.min( nWords-1, data.length-1) ;
0N/A if ( nWords > data.length ){
0N/A r.append( "("+data.length+"<"+nWords+"!)" );
0N/A }
0N/A for( ; i> 0 ; i-- ){
0N/A r.append( Integer.toHexString( data[i] ) );
0N/A r.append(' ');
0N/A }
0N/A r.append( Integer.toHexString( data[0] ) );
0N/A r.append(']');
0N/A return new String( r );
0N/A }
0N/A}