You may have a look at
sun.misc.FloatingDecimal.
Some constants:
Code:
/**
* All the positive powers of 10 that can be
* represented exactly in double/float.
*/
private static final double[] SMALL_10_POW = {
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[] SINGLE_SMALL_10_POW = {
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[] BIG_10_POW = {
1e16, 1e32, 1e64, 1e128, 1e256 };
private static final double[] TINY_10_POW = {
1e-16, 1e-32, 1e-64, 1e-128, 1e-256 };
And then in
ASCIIToBinaryBuffer.doubleValue:
Code:
//
// 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) {
if (decExponent > MAX_DECIMAL_EXPONENT + 1) {
//
// Lets face it. This is going to be
// Infinity. Cut to the chase.
//
return (isNegative) ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
}
if ((exp & 15) != 0) {
dValue *= SMALL_10_POW[exp & 15];
}
if ((exp >>= 4) != 0) {
int j;
for (j = 0; exp > 1; j++, exp >>= 1) {
if ((exp & 1) != 0) {
dValue *= BIG_10_POW[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.
//
double t = dValue * BIG_10_POW[j];
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 *= BIG_10_POW[j];
if (Double.isInfinite(t)) {
return (isNegative) ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
}
t = Double.MAX_VALUE;
}
dValue = t;
}
} else if (exp < 0) {
(…)
Thus in case of
8.25e84 we'd end up with:
8.25 * 1e4 * 1e16 * 1e64
Kind regards
Thomas