NumberConverterpublic final class NumberConverter extends Object
Fields Summary |
---|
private int | setCount | private int | getCount | private int[] | uArray | private int | firstK | private static final double | invLogOfTenBaseTwo | private static final long[] | TEN_TO_THE |
Methods Summary |
---|
private native void | bigIntDigitGeneratorInstImpl(long f, int e, boolean isDenormalized, boolean mantissaIsZero, int p)
| public static java.lang.String | convert(double input)
return getConverter().convertD(input);
| public static java.lang.String | convert(float input)
return getConverter().convertF(input);
| public java.lang.String | convertD(double inputNumber)
int p = 1023 + 52; // the power offset (precision)
long signMask = 0x8000000000000000L; // the mask to get the sign of
// the number
long eMask = 0x7FF0000000000000L; // the mask to get the power bits
long fMask = 0x000FFFFFFFFFFFFFL; // the mask to get the significand
// bits
long inputNumberBits = Double.doubleToLongBits(inputNumber);
// the value of the sign... 0 is positive, ~0 is negative
String signString = (inputNumberBits & signMask) == 0 ? "" : "-";
// the value of the 'power bits' of the inputNumber
int e = (int) ((inputNumberBits & eMask) >> 52);
// the value of the 'significand bits' of the inputNumber
long f = inputNumberBits & fMask;
boolean mantissaIsZero = f == 0;
int pow = 0, numBits = 52;
if (e == 2047)
return mantissaIsZero ? signString + "Infinity" : "NaN";
if (e == 0) {
if (mantissaIsZero)
return signString + "0.0";
if (f == 1)
// special case to increase precision even though 2 *
// Double.MIN_VALUE is 1.0e-323
return signString + "4.9E-324";
pow = 1 - p; // a denormalized number
long ff = f;
while ((ff & 0x0010000000000000L) == 0) {
ff = ff << 1;
numBits--;
}
} else {
// 0 < e < 2047
// a "normalized" number
f = f | 0x0010000000000000L;
pow = e - p;
}
if (-59 < pow && pow < 6 || (pow == -59 && !mantissaIsZero))
longDigitGenerator(f, pow, e == 0, mantissaIsZero, numBits);
else
bigIntDigitGeneratorInstImpl(f, pow, e == 0, mantissaIsZero,
numBits);
if (inputNumber >= 1e7D || inputNumber <= -1e7D
|| (inputNumber > -1e-3D && inputNumber < 1e-3D))
return signString + freeFormatExponential();
return signString + freeFormat();
| public java.lang.String | convertF(float inputNumber)
int p = 127 + 23; // the power offset (precision)
int signMask = 0x80000000; // the mask to get the sign of the number
int eMask = 0x7F800000; // the mask to get the power bits
int fMask = 0x007FFFFF; // the mask to get the significand bits
int inputNumberBits = Float.floatToIntBits(inputNumber);
// the value of the sign... 0 is positive, ~0 is negative
String signString = (inputNumberBits & signMask) == 0 ? "" : "-";
// the value of the 'power bits' of the inputNumber
int e = (inputNumberBits & eMask) >> 23;
// the value of the 'significand bits' of the inputNumber
int f = inputNumberBits & fMask;
boolean mantissaIsZero = f == 0;
int pow = 0, numBits = 23;
if (e == 255)
return mantissaIsZero ? signString + "Infinity" : "NaN";
if (e == 0) {
if (mantissaIsZero)
return signString + "0.0";
pow = 1 - p; // a denormalized number
if (f < 8) { // want more precision with smallest values
f = f << 2;
pow -= 2;
}
int ff = f;
while ((ff & 0x00800000) == 0) {
ff = ff << 1;
numBits--;
}
} else {
// 0 < e < 255
// a "normalized" number
f = f | 0x00800000;
pow = e - p;
}
if (-59 < pow && pow < 35 || (pow == -59 && !mantissaIsZero))
longDigitGenerator(f, pow, e == 0, mantissaIsZero, numBits);
else
bigIntDigitGeneratorInstImpl(f, pow, e == 0, mantissaIsZero,
numBits);
if (inputNumber >= 1e7f || inputNumber <= -1e7f
|| (inputNumber > -1e-3f && inputNumber < 1e-3f))
return signString + freeFormatExponential();
return signString + freeFormat();
| private java.lang.String | freeFormat()
// corresponds to process "Free-Format"
char[] formattedDecimal = new char[25];
// the position the next character is to be inserted into
// formattedDecimal
int charPos = 0;
int k = firstK;
if (k < 0) {
formattedDecimal[0] = '0";
formattedDecimal[1] = '.";
charPos += 2;
for (int i = k + 1; i < 0; i++)
formattedDecimal[charPos++] = '0";
}
int U = uArray[getCount++];
do {
if (U != -1)
formattedDecimal[charPos++] = (char) ('0" + U);
else if (k >= -1)
formattedDecimal[charPos++] = '0";
if (k == 0)
formattedDecimal[charPos++] = '.";
k--;
U = getCount < setCount ? uArray[getCount++] : -1;
} while (U != -1 || k >= -1);
return new String(formattedDecimal, 0, charPos);
| private java.lang.String | freeFormatExponential()
// corresponds to process "Free-Format Exponential"
char[] formattedDecimal = new char[25];
formattedDecimal[0] = (char) ('0" + uArray[getCount++]);
formattedDecimal[1] = '.";
// the position the next character is to be inserted into
// formattedDecimal
int charPos = 2;
int k = firstK;
int expt = k;
while (true) {
k--;
if (getCount >= setCount)
break;
formattedDecimal[charPos++] = (char) ('0" + uArray[getCount++]);
}
if (k == expt - 1)
formattedDecimal[charPos++] = '0";
formattedDecimal[charPos++] = 'E";
return new String(formattedDecimal, 0, charPos)
+ Integer.toString(expt);
| private static org.apache.harmony.luni.util.NumberConverter | getConverter()
TEN_TO_THE[0] = 1L;
for (int i = 1; i < TEN_TO_THE.length; ++i) {
long previous = TEN_TO_THE[i - 1];
TEN_TO_THE[i] = (previous << 1) + (previous << 3);
}
return new NumberConverter();
| private void | longDigitGenerator(long f, int e, boolean isDenormalized, boolean mantissaIsZero, int p)
long R, S, M;
if (e >= 0) {
M = 1l << e;
if (!mantissaIsZero) {
R = f << (e + 1);
S = 2;
} else {
R = f << (e + 2);
S = 4;
}
} else {
M = 1;
if (isDenormalized || !mantissaIsZero) {
R = f << 1;
S = 1l << (1 - e);
} else {
R = f << 2;
S = 1l << (2 - e);
}
}
int k = (int) Math.ceil((e + p - 1) * invLogOfTenBaseTwo - 1e-10);
if (k > 0) {
S = S * TEN_TO_THE[k];
} else if (k < 0) {
long scale = TEN_TO_THE[-k];
R = R * scale;
M = M == 1 ? scale : M * scale;
}
if (R + M > S) { // was M_plus
firstK = k;
} else {
firstK = k - 1;
R = R * 10;
M = M * 10;
}
getCount = setCount = 0; // reset indices
boolean low, high;
int U;
long[] Si = new long[] { S, S << 1, S << 2, S << 3 };
while (true) {
// set U to be floor (R / S) and R to be the remainder
// using a kind of "binary search" to find the answer.
// It's a lot quicker than actually dividing since we know
// the answer will be between 0 and 10
U = 0;
long remainder;
for (int i = 3; i >= 0; i--) {
remainder = R - Si[i];
if (remainder >= 0) {
R = remainder;
U += 1 << i;
}
}
low = R < M; // was M_minus
high = R + M > S; // was M_plus
if (low || high)
break;
R = R * 10;
M = M * 10;
uArray[setCount++] = U;
}
if (low && !high)
uArray[setCount++] = U;
else if (high && !low)
uArray[setCount++] = U + 1;
else if ((R << 1) < S)
uArray[setCount++] = U;
else
uArray[setCount++] = U + 1;
|
|