/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
public class FormattedFloatingDecimal{
boolean isExceptional;
boolean isNegative;
int decExponentRounded;
char digits[];
int nDigits;
int bigIntExp;
int bigIntNBits;
boolean mustSetRoundDir = false;
boolean fromHex = false;
private FormattedFloatingDecimal( boolean negSign, int decExponent, char []digits, int n, boolean e, int precision, Form form )
{
isExceptional = e;
this.decExponent = decExponent;
this.nDigits = n;
}
/*
* Constants of the implementation
* Most are IEEE-754 related.
* (There are more really boring constants at the end.)
*/
/*
* count number of bits from high-order 1 bit to low-order 1 bit,
* inclusive.
*/
private static int
countBits( long v ){
//
// the strategy is to shift until we get a non-zero sign bit
// then shift until we have no bits left, counting the difference.
// we do byte shifting as a hack. Hope it helps.
//
if ( v == 0L ) return 0;
while ( ( v & highbyte ) == 0L ){
v <<= 8;
}
while ( v > 0L ) { // i.e. while ((v&highbit) == 0L )
v <<= 1;
}
int n = 0;
while (( v & lowbytes ) != 0L ){
v <<= 8;
n += 8;
}
while ( v != 0L ){
v <<= 1;
n += 1;
}
return n;
}
/*
* Keep big powers of 5 handy for future reference.
*/
private static synchronized FDBigInt
big5pow( int p ){
assert p >= 0 : p; // negative power of 5
b5p = t;
}
return b5p[p];
else {
// construct the value.
// recursively.
int q, r;
// in order to compute 5^p,
// compute its square root, 5^(p/2) and square.
// or, let q = p / 2, r = p -q, then
// 5^p = 5^(q+r) = 5^q * 5^r
q = p >> 1;
r = p - q;
}else{
}
}
}
//
// a common operation
//
private static FDBigInt
if ( p5 != 0 ){
} else {
}
}
if ( p2 != 0 ){
}
return v;
}
//
// another common operation
//
private static FDBigInt
if ( p2 != 0 ){
}
return v;
}
/*
* Make a floating double into a FDBigInt.
* This could also be structured as a FDBigInt
* constructor, but we'd have to build a lot of knowledge
* about floating-point representation into it, and we don't want to.
*
* AS A SIDE EFFECT, THIS METHOD WILL SET THE INSTANCE VARIABLES
* bigIntExp and bigIntNBits
*
*/
private FDBigInt
if ( binexp > 0 ){
} else {
binexp +=1;
lbits <<= 1;
binexp -= 1;
}
}
/*
* We now know where the high-order 1 bit is,
* and we know how many there are.
*/
lbits >>>= lowOrderZeros;
bigIntNBits = nbits;
}
/*
* Compute a number that is the ULP of the given value,
* for purposes of addition/subtraction. Generally easy.
* More difficult if subtracting and the argument
* is a normalized a power of 2, as the ULP changes at these points.
*/
double ulpval;
// for subtraction from normalized, powers of 2,
// use next-smaller exponent
binexp -= 1;
}
} else if ( binexp == 0 ){
} else {
}
return ulpval;
}
/*
* Round a double to a float.
* In addition to the fraction bits of the double,
* look at the class instance variable roundDir,
* which should help us avoid double-rounding error.
* roundDir was set in hardValueOf if the estimate was
* close enough, but not exact. It tells us which direction
* of rounding is preferred.
*/
float
// what we have here is special.
// don't worry, the right thing will happen.
return (float) dval;
}
}
/*
* This is the easy subcase --
* all the significant bits, after scaling, are held in lvalue.
* negSign and decExponent tell us what processing and scaling
* has already been done. Exceptional cases have already been
* stripped out.
* In particular:
* lvalue is a finite number (not Inf, nor NaN)
* lvalue > 0L (not zero, nor negative).
*
* The only reason that we develop the digits here, rather than
* calling on Long.toString() is that we can do it a little faster,
* and besides want to treat trailing 0s specially. If Long.toString
* changes, we should re-evaluate this strategy!
*/
private void
char digits[];
int ndigits;
int digitno;
int c;
//
// Discard non-significant low-order bits, while rounding,
// up to insignificant value.
int i;
insignificant /= 10L;
if ( i != 0 ){
decExponent += i;
// round up based on the low-order bits we're discarding
lvalue++;
}
}
// even easier subcase!
// can do int arithmetic rather than long!
ndigits = 10;
c = ivalue%10;
ivalue /= 10;
while ( c == 0 ){
decExponent++;
c = ivalue%10;
ivalue /= 10;
}
while ( ivalue != 0){
decExponent++;
c = ivalue%10;
ivalue /= 10;
}
} else {
// same algorithm as above (same bugs, too )
// but using long arithmetic.
ndigits = 20;
c = (int)(lvalue%10L);
lvalue /= 10L;
while ( c == 0 ){
decExponent++;
c = (int)(lvalue%10L);
lvalue /= 10L;
}
while ( lvalue != 0L ){
decExponent++;
c = (int)(lvalue%10L);
lvalue /= 10;
}
}
char result [];
}
//
// add one to the least significant digit.
// in the unlikely event there is a carry out,
// deal with it.
// assert that this will only happen where there
// is only one digit, e.g. (float)1e-44 seems to do it.
//
private void
roundup(){
int i;
if ( q == '9' ){
while ( q == '9' && i > 0 ){
digits[i] = '0';
q = digits[--i];
}
if ( q == '9' ){
// carryout! High-order 1, rest 0s, larger exp.
decExponent += 1;
return;
}
// else fall through.
}
digits[i] = (char)(q+1);
}
// Given the desired number of digits predict the result's exponent.
return decExponent;
for (int i = 0; i < length; i++)
if (digits[i] != '9')
// a '9' anywhere in digits will absorb the round
return decExponent;
}
// Unlike roundup(), this method does not modify digits. It also
// rounds at a particular precision.
// no rounding necessary
return result;
}
if (length == 0) {
// only one digit (0 or 1) is returned because the precision
// excludes all significant digits
}
return result;
}
int i = length;
int q = digits[i];
if (q >= '5' && i > 0) {
q = digits[--i];
if ( q == '9' ) {
while ( q == '9' && i > 0 ){
q = digits[--i];
}
if ( q == '9' ){
// carryout! High-order 1, rest 0s, larger exp.
return result;
}
}
result[i] = (char)(q + 1);
}
while (--i >= 0) {
}
return result;
}
/*
* FIRST IMPORTANT CONSTRUCTOR: DOUBLE
*/
public FormattedFloatingDecimal( double d )
{
}
{
long fractBits;
int binExp;
int nSignificantBits;
// discover and delete sign
isNegative = true;
} else {
isNegative = false;
}
// Begin to unpack
// Discover obvious special cases of NaN and Infinity.
isExceptional = true;
if ( fractBits == 0L ){
} else {
digits = notANumber;
isNegative = false; // NaN has no sign!
}
return;
}
isExceptional = false;
// Finish unpacking
// Normalize denormalized numbers.
// Insert assumed high-order bit for normalized numbers.
// Subtract exponent bias.
if ( binExp == 0 ){
if ( fractBits == 0L ){
// not a denorm, just a 0!
decExponent = 0;
nDigits = 1;
return;
}
fractBits <<= 1;
binExp -= 1;
}
binExp += 1;
} else {
}
// call the routine that actually does all the hard work.
}
/*
* SECOND IMPORTANT CONSTRUCTOR: SINGLE
*/
public FormattedFloatingDecimal( float f )
{
}
{
int fractBits;
int binExp;
int nSignificantBits;
// discover and delete sign
isNegative = true;
fBits ^= singleSignMask;
} else {
isNegative = false;
}
// Begin to unpack
// Discover obvious special cases of NaN and Infinity.
isExceptional = true;
if ( fractBits == 0L ){
} else {
digits = notANumber;
isNegative = false; // NaN has no sign!
}
return;
}
isExceptional = false;
// Finish unpacking
// Normalize denormalized numbers.
// Insert assumed high-order bit for normalized numbers.
// Subtract exponent bias.
if ( binExp == 0 ){
if ( fractBits == 0 ){
// not a denorm, just a 0!
decExponent = 0;
nDigits = 1;
return;
}
fractBits <<= 1;
binExp -= 1;
}
binExp += 1;
} else {
}
binExp -= singleExpBias;
// call the routine that actually does all the hard work.
}
private void
{
int nFractBits; // number of significant bits of fractBits;
int nTinyBits; // number of these to the right of the point.
int decExp;
// Examine number. Determine if it is an easy case,
// or whether we must do real work.
// Look more closely at the number to decide if,
// with scaling by 10^nTinyBits, the result will fit in
// a long.
/*
* We can do this:
* take the fraction bits, which are normalized.
* (a) nTinyBits == 0: Shift left or right appropriately
* to align the binary point at the extreme right, i.e.
* where a long int point is expected to be. The integer
* result is easily converted to a string.
* (b) nTinyBits > 0: Shift right by expShift-nFractBits,
* which effectively converts to long and scales by
* 2^nTinyBits. Then multiply by 5^nTinyBits to
* complete the scaling. We know this won't overflow
* because we just counted the number of bits necessary
* in the result. The integer you get from this can
* then be converted to a string pretty easily.
*/
long halfULP;
if ( nTinyBits == 0 ) {
if ( binExp > nSignificantBits ){
} else {
halfULP = 0L;
}
} else {
}
return;
}
/*
* The following causes excess digits to be printed
* out in the single-float case. Our manipulation of
* halfULP here is apparently not correct. If we
* better understand how this works, perhaps we can
* use this special case again. But for the time being,
* we do not.
* else {
* fractBits >>>= expShift+1-nFractBits;
* fractBits *= long5pow[ nTinyBits ];
* halfULP = long5pow[ nTinyBits ] >> (1+nSignificantBits-nFractBits);
* developLongDigits( -nTinyBits, fractBits, halfULP );
* return;
* }
*/
}
}
/*
* This is the hard case. We are going to compute large positive
* integers B and S and integer decExp, s.t.
* d = ( B / S ) * 10^decExp
* 1 <= B / S < 10
* Obvious choices are:
* decExp = floor( log10(d) )
* B = d * 2^nTinyBits * 10^max( 0, -decExp )
* S = 10^max( 0, decExp) * 2^nTinyBits
* (noting that nTinyBits has already been forced to non-negative)
* I am also going to compute a large positive integer
* M = (1/2^nSignificantBits) * 2^nTinyBits * 10^max( 0, -decExp )
* i.e. M is (1/2) of the ULP of d, scaled like B.
* When we iterate through dividing B/S and picking off the
* quotient bits, we will know when to stop when the remainder
* is <= M.
*
* We keep track of powers of 2 and powers of 5.
*/
/*
* Estimate decimal exponent. (If it is small-ish,
* we could double-check.)
*
* First, scale the mantissa bits such that 1 <= d2 < 2.
* We are then going to estimate
* log10(d2) ~=~ (d2-1.5)/1.5 + log(1.5)
* and so we can estimate
* log10(d) ~=~ log10(d2) + binExp * log10(2)
* take the floor and call it decExp.
* FIXME -- use more precise constants here. It costs no more.
*/
int Bbits; // binary digits needed to represent B, approx.
int tenSbits; // binary digits needed to represent 10*S, approx.
/*
* the long integer fractBits contains the (nFractBits) interesting
* bits from the mantissa of d ( hidden 1 added if necessary) followed
* by (expShift+1-nFractBits) zeros. In the interest of compactness,
* I will shift out those zeros before turning fractBits into a
* FDBigInt. The resulting whole number will be
* d * 2^(nFractBits-1-binExp).
*/
B2 -= common2factor;
S2 -= common2factor;
M2 -= common2factor;
/*
* HACK!! For exact powers of two, the next smallest number
* is only half as far away as we think (because the meaning of
* ULP changes at power-of-two bounds) for this reason, we
* hack M2. Hope this works.
*/
if ( nFractBits == 1 )
M2 -= 1;
if ( M2 < 0 ){
// oops.
// since we cannot scale M down far enough,
// we must scale the other values up.
M2 = 0;
}
/*
* Construct, Scale, iterate.
* Some day, we'll write a stopping test that takes
* account of the assymetry of the spacing of floating-point
* numbers below perfect powers of 2
* 26 Sept 96 is not that day.
* So we use a symmetric test.
*/
int ndigit = 0;
long lowDigitDifference;
int q;
/*
* Detect the special cases where all the numbers we are about
* to compute will fit in int or long integers.
* In these cases, we will avoid doing FDBigInt arithmetic.
* We use the same algorithms, except that we "normalize"
* our FDBigInts before iterating. This is to make division easier,
* as it makes our fist guess (quotient of high-order words)
* more accurate!
*
* Some day, we'll write a stopping test that takes
* account of the assymetry of the spacing of floating-point
* numbers below perfect powers of 2
* 26 Sept 96 is not that day.
* So we use a symmetric test.
*/
// wa-hoo! They're all ints!
int tens = s * 10;
/*
* Unroll the first iteration. If our decExp estimate
* was too high, our first quotient will be zero. In this
* case, we discard it and decrement decExp.
*/
ndigit = 0;
q = b / s;
b = 10 * ( b % s );
m *= 10;
low = (b < m );
assert q < 10 : q; // excessively large digit
if ( (q == 0) && ! high ){
// oops. Usually ignore leading zero.
decExp--;
} else {
}
/*
* HACK! Java spec sez that we always have at least
* one digit after the . in either F- or E-form output.
* Thus we will need more than one digit if we're using
* E-form
*/
}
q = b / s;
b = 10 * ( b % s );
m *= 10;
assert q < 10 : q; // excessively large digit
if ( m > 0L ){
low = (b < m );
} else {
// hack -- m might overflow!
// in this case, it is certainly > b,
// which won't
// and b+m > tens, too, since that has overflowed
// either!
low = true;
high = true;
}
}
} else {
// still good! they're all longs!
long tens = s * 10L;
/*
* Unroll the first iteration. If our decExp estimate
* was too high, our first quotient will be zero. In this
* case, we discard it and decrement decExp.
*/
ndigit = 0;
q = (int) ( b / s );
b = 10L * ( b % s );
m *= 10L;
low = (b < m );
assert q < 10 : q; // excessively large digit
if ( (q == 0) && ! high ){
// oops. Usually ignore leading zero.
decExp--;
} else {
}
/*
* HACK! Java spec sez that we always have at least
* one digit after the . in either F- or E-form output.
* Thus we will need more than one digit if we're using
* E-form
*/
}
q = (int) ( b / s );
b = 10 * ( b % s );
m *= 10;
assert q < 10 : q; // excessively large digit
if ( m > 0L ){
low = (b < m );
} else {
// hack -- m might overflow!
// in this case, it is certainly > b,
// which won't
// and b+m > tens, too, since that has overflowed
// either!
low = true;
high = true;
}
}
}
} else {
int shiftBias;
/*
* We really must do FDBigInt arithmetic.
* Fist, construct our FDBigInt initial values.
*/
// normalize so that division works better
/*
* Unroll the first iteration. If our decExp estimate
* was too high, our first quotient will be zero. In this
* case, we discard it and decrement decExp.
*/
ndigit = 0;
assert q < 10 : q; // excessively large digit
if ( (q == 0) && ! high ){
// oops. Usually ignore leading zero.
decExp--;
} else {
}
/*
* HACK! Java spec sez that we always have at least
* one digit after the . in either F- or E-form output.
* Thus we will need more than one digit if we're using
* E-form
*/
}
assert q < 10 : q; // excessively large digit
}
} else
}
/*
* Last digit gets rounded based on stopping condition.
*/
if ( high ){
if ( low ){
if ( lowDigitDifference == 0L ){
// it's a tie!
// choose based on which digits we like.
} else if ( lowDigitDifference > 0 ){
roundup();
}
} else {
roundup();
}
}
}
public String
toString(){
// most brain-dead version
if ( isExceptional ){
} else {
}
}
// returns the exponent before rounding
public int getExponent() {
return decExponent - 1;
}
// returns the exponent after rounding has been done by applyPrecision
public int getExponentRounded() {
return decExponentRounded - 1;
}
int i = 0;
if (isExceptional) {
i += nDigits;
} else {
int exp = decExponent;
switch (form) {
case COMPATIBLE:
break;
case DECIMAL_FLOAT:
break;
case SCIENTIFIC:
break;
case GENERAL:
// adjust precision to be the number of digits to right of decimal
// the real exponent to be output is actually exp - 1, not exp
precision--;
} else {
}
break;
default:
assert false;
}
if (exp > 0
{
// print digits.digits.
i += charLength;
if (charLength < exp) {
result[i++] = '0';
// Do not append ".0" for formatted floats since the user
// may request that it be omitted. It is added as necessary
// by the Formatter.
result[i++] = '.';
result[i++] = '0';
}
} else {
// Do not append ".0" for formatted floats since the user
// may request that it be omitted. It is added as necessary
// by the Formatter.
result[i++] = '.';
if (charLength < nDigits) {
i += t;
} else {
result[i++] = '0';
}
} else {
if (t > 0) {
result[i++] = '.';
i += t;
}
}
}
} else if (exp <= 0
{
// print 0.0* digits
result[i++] = '0';
if (exp != 0) {
// write '0' s before the significant digits
if (t > 0) {
result[i++] = '.';
result[i++] = '0';
}
}
if (t > 0) {
if (i == 1)
result[i++] = '.';
// copy only when significant digits are within the precision
i += t;
}
} else {
result[i++] = '.';
if (nDigits > 1) {
i += nDigits-1;
} else {
result[i++] = '0';
}
result[i++] = 'E';
} else {
if (nDigits > 1) {
if (t > 0) {
result[i++] = '.';
i += t;
}
}
result[i++] = 'e';
}
int e;
if (exp <= 0) {
result[i++] = '-';
e = -exp+1;
} else {
result[i++] = '+';
e = exp-1;
}
// decExponent has 1, 2, or 3, digits
if (e <= 9) {
result[i++] = '0';
result[i++] = (char)(e+'0');
} else if (e <= 99) {
} else {
e %= 100;
}
}
}
return i;
}
// Per-thread buffer for string/stringbuffer conversion
protected synchronized Object initialValue() {
return new char[26];
}
};
/*
* Take a FormattedFloatingDecimal, which we presumably just scanned in,
* and find out what its value is, as a double.
*
* AS A SIDE EFFECT, SET roundDir TO INDICATE PREFERRED
* ROUNDING DIRECTION in case the result is really destined
* for a single-precision float.
*/
public strictfp double doubleValue(){
long lValue;
double dValue;
// First, check for NaN and Infinity values
if(digits == notANumber)
else
}
else {
if (mustSetRoundDir) {
roundDir = 0;
}
/*
* convert the lead kDigits to a long integer.
*/
// (special performance hack: start to do it using int)
for ( int i=1; i < iDigits; i++ ){
}
}
/*
* lValue now contains a long integer with the value of
* the first kDigits digits of the number.
* dValue contains the (double) of the same.
*/
if ( nDigits <= maxDecimalDigits ){
/*
* possibly an easy case.
* We know that the digits can be represented
* exactly. And if the exponent isn't too outrageous,
* the whole thing can be done with one operation,
* thus one rounding error.
* Note that all our constructors trim all leading and
* trailing zeros, so simple values (including zero)
* will always end up here
*/
else if ( exp >= 0 ){
if ( exp <= maxSmallTen ){
/*
* Can get the answer with one operation,
* thus one roundoff.
*/
if ( mustSetRoundDir ){
: -1;
}
}
/*
* We can multiply dValue by 10^(slop)
* and it is still "small" and exact.
* Then we can multiply by 10^(exp-slop)
* with one rounding.
*/
if ( mustSetRoundDir ){
: -1;
}
}
/*
* Else we have a hard case with a positive exp.
*/
} else {
if ( exp >= -maxSmallTen ){
/*
* Can get the answer in one division.
*/
if ( mustSetRoundDir ){
: -1;
}
}
/*
* Else we have a hard case with a negative exp.
*/
}
}
/*
* Harder cases:
* The sum of digits plus exponent is greater than
* what we think we can do with one error.
*
* Start by approximating the right answer by,
* naively, scaling by powers of 10.
*/
if ( exp > 0 ){
/*
* Lets face it. This is going to be
* Infinity. Cut to the chase.
*/
}
}
int j;
}
/*
* The reason for the weird exp > 1 condition
* in the above loop was so that the last multiply
* would get unrolled. We handle it here.
* It could overflow.
*/
if ( Double.isInfinite( t ) ){
/*
* It did overflow.
* Look more closely at the result.
* If the exponent is just one too large,
* then use the maximum finite as our estimate
* value. Else call the result infinity
* and punt it.
* ( I presume this could happen because
* rounding forces the result here to be
* an ULP or two larger than
* Double.MAX_VALUE ).
*/
t = dValue / 2.0;
t *= big10pow[j];
if ( Double.isInfinite( t ) ){
}
}
dValue = t;
}
} else if ( exp < 0 ){
/*
* Lets face it. This is going to be
* zero. Cut to the chase.
*/
}
}
int j;
}
/*
* The reason for the weird exp > 1 condition
* in the above loop was so that the last multiply
* would get unrolled. We handle it here.
* It could underflow.
*/
if ( t == 0.0 ){
/*
* It did underflow.
* Look more closely at the result.
* If the exponent is just one too small,
* then use the minimum finite as our estimate
* value. Else call the result 0.0
* and punt it.
* ( I presume this could happen because
* rounding forces the result here to be
* an ULP or two less than
* Double.MIN_VALUE ).
*/
t = dValue * 2.0;
t *= tiny10pow[j];
if ( t == 0.0 ){
}
}
dValue = t;
}
}
/*
* dValue is now approximately the result.
* The hard part is adjusting it, by comparison
* with FDBigInt arithmetic.
* Formulate the EXACT big-number result as
* bigD0 * 10^exp
*/
while(true){
/* AS A SIDE EFFECT, THIS METHOD WILL SET THE INSTANCE VARIABLES
* bigIntExp and bigIntNBits
*/
/*
* Scale bigD, bigB appropriately for
* big-integer operations.
* Naively, we multipy by powers of ten
* and powers of two. What we actually do
* is keep track of the powers of 5 and
* powers of 2 we would use, then factor out
* common divisors before doing the work.
*/
int Ulp2; // powers of 2 in halfUlp.
if ( exp >= 0 ){
} else {
}
if ( bigIntExp >= 0 ){
} else {
}
// shift bigB and bigD left by a number s. t.
// halfUlp is still an integer.
int hulpbias;
// This is going to be a denormalized number
// (if not actually zero).
// half an ULP is at 2^-(expBias+expShift+1)
} else {
}
// if there are common factors of 2, we might just as well
// factor them out, as they add nothing useful.
// do multiplications by powers of 5 and 2
//
// to recap:
// bigB is the scaled-big-int version of our floating-point
// candidate.
// bigD is the scaled-big-int version of the exact value
// as we understand it.
// halfUlp is 1/2 an ulp of bigB, except for special cases
// of exact powers of 2
//
// the plan is to compare bigB with bigD, and if the difference
// is less than halfUlp, then we're satisfied. Otherwise,
// use the ratio of difference to halfUlp to calculate a fudge
// factor to add to the floating value, then go 'round again.
//
int cmpResult;
boolean overvalue;
overvalue = true; // our candidate is too big.
// candidate is a normalized exact power of 2 and
// is too big. We will be subtracting.
// For our purposes, ulp is the ulp of the
// next smaller range.
Ulp2 -= 1;
if ( Ulp2 < 0 ){
// rats. Cannot de-scale ulp this far.
// must scale diff in other direction.
Ulp2 = 0;
}
}
} else if ( cmpResult < 0 ){
overvalue = false; // our candidate is too small.
} else {
// the candidate is exactly right!
// this happens with surprising fequency
break correctionLoop;
}
// difference is small.
// this is close enough
if (mustSetRoundDir) {
}
break correctionLoop;
} else if ( cmpResult == 0 ){
// difference is exactly half an ULP
// round to some other value maybe, then finish
// should check for bigIntNBits == 1 here??
if (mustSetRoundDir) {
}
break correctionLoop;
} else {
// difference is non-trivial.
// could scale addend by ratio of difference to
// halfUlp here, if we bothered to compute that difference.
// Most of the time ( I hope ) it is about 1 anyway.
break correctionLoop; // oops. Fell off end of range.
continue; // try again.
}
}
}
}
/*
* Take a FormattedFloatingDecimal, which we presumably just scanned in,
* and find out what its value is, as a float.
* This is distinct from doubleValue() to avoid the extremely
* unlikely case of a double rounding error, wherein the converstion
* to double has one rounding error, and the conversion of that double
* to a float has another rounding error, IN THE WRONG DIRECTION,
* ( because of the preference to a zero low-order bit ).
*/
public strictfp float floatValue(){
int iValue;
float fValue;
// First, check for NaN and Infinity values
if(digits == notANumber)
else
}
else {
/*
* convert the lead kDigits to an integer.
*/
for ( int i=1; i < kDigits; i++ ){
}
/*
* iValue now contains an integer with the value of
* the first kDigits digits of the number.
* fValue contains the (float) of the same.
*/
if ( nDigits <= singleMaxDecimalDigits ){
/*
* possibly an easy case.
* We know that the digits can be represented
* exactly. And if the exponent isn't too outrageous,
* the whole thing can be done with one operation,
* thus one rounding error.
* Note that all our constructors trim all leading and
* trailing zeros, so simple values (including zero)
* will always end up here.
*/
else if ( exp >= 0 ){
if ( exp <= singleMaxSmallTen ){
/*
* Can get the answer with one operation,
* thus one roundoff.
*/
}
/*
* We can multiply dValue by 10^(slop)
* and it is still "small" and exact.
* Then we can multiply by 10^(exp-slop)
* with one rounding.
*/
}
/*
* Else we have a hard case with a positive exp.
*/
} else {
if ( exp >= -singleMaxSmallTen ){
/*
* Can get the answer in one division.
*/
}
/*
* Else we have a hard case with a negative exp.
*/
}
/*
* In double-precision, this is an exact floating integer.
* So we can compute to double, then shorten to float
* with one round, and get the right answer.
*
* First, finish accumulating digits.
* Then convert that integer to a double, multiply
* by the appropriate power of ten, and convert to float.
*/
}
}
/*
* Harder cases:
* The sum of digits plus exponent is greater than
* what we think we can do with one error.
*
* Start by weeding out obviously out-of-range
* results, then convert to double and go to
* common hard-case code.
*/
/*
* Lets face it. This is going to be
* Infinity. Cut to the chase.
*/
/*
* Lets face it. This is going to be
* zero. Cut to the chase.
*/
}
/*
* Here, we do 'way too much work, but throwing away
* our partial results, and going and doing the whole
* thing as double, then throwing away half the bits that computes
* when we convert back to float.
*
* The alternative is to reproduce the whole multiple-precision
* algorythm for float precision, or to try to parameterize it
* for common usage. The former will take about 400 lines of code,
* and the latter I tried without success. Thus the semi-hack
* answer here.
*/
double dValue = doubleValue();
return stickyRound( dValue );
}
}
/*
* All the positive powers of 10 that can be
*/
private static final double small10pow[] = {
1.0e0,
1.0e1, 1.0e2, 1.0e3, 1.0e4, 1.0e5,
1.0e6, 1.0e7, 1.0e8, 1.0e9, 1.0e10,
1.0e11, 1.0e12, 1.0e13, 1.0e14, 1.0e15,
1.0e16, 1.0e17, 1.0e18, 1.0e19, 1.0e20,
1.0e21, 1.0e22
};
private static final float singleSmall10pow[] = {
1.0e0f,
1.0e1f, 1.0e2f, 1.0e3f, 1.0e4f, 1.0e5f,
1.0e6f, 1.0e7f, 1.0e8f, 1.0e9f, 1.0e10f
};
private static final double big10pow[] = {
1e16, 1e32, 1e64, 1e128, 1e256 };
private static final double tiny10pow[] = {
1e-16, 1e-32, 1e-64, 1e-128, 1e-256 };
private static final int small5pow[] = {
1,
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*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*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*5*5*5,
5*5*5*5*5*5*5*5*5*5*5*5*5
};
private static final long long5pow[] = {
1L,
5L,
5L*5,
5L*5*5,
5L*5*5*5,
5L*5*5*5*5,
5L*5*5*5*5*5,
5L*5*5*5*5*5*5,
5L*5*5*5*5*5*5*5,
5L*5*5*5*5*5*5*5*5,
5L*5*5*5*5*5*5*5*5*5,
5L*5*5*5*5*5*5*5*5*5*5,
5L*5*5*5*5*5*5*5*5*5*5*5,
5L*5*5*5*5*5*5*5*5*5*5*5*5,
5L*5*5*5*5*5*5*5*5*5*5*5*5*5,
5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5,
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,
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,
};
// approximately ceil( log2( long5pow[i] ) )
private static final int n5bits[] = {
0,
3,
5,
7,
10,
12,
14,
17,
19,
21,
24,
26,
28,
31,
33,
35,
38,
40,
42,
45,
47,
49,
52,
54,
56,
59,
61,
};
}