public static double parseDouble()

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;
  }