in tajo-common/src/main/java/org/apache/tajo/util/Bytes.java [1968:2137]
public static double parseDouble(byte[] bytes, int start, int length) {
if (bytes == null) {
throw new NumberFormatException("String is null");
}
if (length == 0) {
throw new NumberFormatException("Empty byte array!");
}
/*
* Strip off leading blanks
*/
int offset = start;
int end = start + length;
while (offset < end && bytes[offset] == ' ') {
offset++;
}
if (offset == end) {
throw new NumberFormatException("blank byte array!");
}
/*
* check for a sign.
*/
boolean sign = false;
if (bytes[offset] == '-') {
sign = true;
offset++;
} else if (bytes[offset] == '+') {
offset++;
}
if (offset == end) {
throw new NumberFormatException("the byte array only has a sign!");
}
/*
* Count the number of digits in the mantissa (including the decimal
* point), and also locate the decimal point.
*/
int mantSize = 0; /* Number of digits in mantissa. */
int decicalOffset = -1; /* Number of mantissa digits BEFORE decimal point. */
for (; offset < end; offset++) {
if (!isDigit(bytes[offset])) {
if ((bytes[offset] != '.') || (decicalOffset >= 0)) {
break;
}
decicalOffset = mantSize;
}
mantSize++;
}
int exponentOffset = offset; /* Temporarily holds location of exponent in bytes. */
/*
* Now suck up the digits in the mantissa. Use two integers to
* collect 9 digits each (this is faster than using floating-point).
* If the mantissa has more than 18 digits, ignore the extras, since
* they can't affect the value anyway.
*/
offset -= mantSize;
if (decicalOffset < 0) {
decicalOffset = mantSize;
} else {
mantSize -= 1; /* One of the digits was the decimal point. */
}
int fracExponent; /* Exponent that derives from the fractional
* part. Under normal circumstatnces, it is
* the negative of the number of digits in F.
* However, if I is very long, the last digits
* of I get dropped (otherwise a long I with a
* large negative exponent could cause an
* unnecessary overflow on I alone). In this
* case, fracExp is incremented one for each
* dropped digit. */
if (mantSize > 18) {
fracExponent = decicalOffset - 18;
mantSize = 18;
} else {
fracExponent = decicalOffset - mantSize;
}
if (mantSize == 0) {
return 0.0;
}
int frac1 = 0;
for (; mantSize > 9; mantSize--) {
int b = bytes[offset];
offset++;
if (b == '.') {
b = bytes[offset];
offset++;
}
frac1 = 10 * frac1 + (b - '0');
}
int frac2 = 0;
for (; mantSize > 0; mantSize--) {
int b = bytes[offset];
offset++;
if (b == '.') {
b = bytes[offset];
offset++;
}
frac2 = 10 * frac2 + (b - '0');
}
double fraction = (1.0e9 * frac1) + frac2;
/*
* Skim off the exponent.
*/
int exponent = 0; /* Exponent read from "EX" field. */
offset = exponentOffset;
boolean expSign = false;
if (offset < end) {
if ((bytes[offset] != 'E') && (bytes[offset] != 'e')) {
throw new NumberFormatException(new String(bytes, start,
length));
}
// (bytes[offset] == 'E') || (bytes[offset] == 'e')
offset++;
if (bytes[offset] == '-') {
expSign = true;
offset++;
} else if (bytes[offset] == '+') {
offset++;
}
for (; offset < end; offset++) {
if (isDigit(bytes[offset])) {
exponent = exponent * 10 + (bytes[offset] - '0');
} else {
throw new NumberFormatException(new String(bytes, start,
length));
}
}
}
exponent = expSign ? (fracExponent - exponent) : (fracExponent + exponent);
/*
* Generate a floating-point number that represents the exponent.
* Do this by processing the exponent one bit at a time to combine
* many powers of 2 of 10. Then combine the exponent with the
* fraction.
*/
if (exponent < 0) {
expSign = true;
exponent = -exponent;
} else {
expSign = false;
}
if (exponent > maxExponent) {
throw new NumberFormatException(new String(bytes, start,
length));
}
double dblExp = 1.0;
for (int i = 0; exponent != 0; exponent >>= 1, i++) {
if ((exponent & 01) == 01) {
dblExp *= powersOf10[i];
}
}
fraction = (expSign) ? (fraction / dblExp) : (fraction * dblExp);
return sign ? (-fraction) : fraction;
}