private BigInteger castBigDecimal2BigInteger()

in odps-sdk/odps-sdk-core/src/main/java/com/aliyun/odps/tunnel/hasher/DefaultHashFactory.java [407:486]


    private BigInteger castBigDecimal2BigInteger(String input, int resultPrecision, int resultScale)
        throws IllegalArgumentException {
      // trim
      input = input.trim();
      int len = input.length();
      int ptr = 0;

      // check negative
      boolean isNegative = false;
      if (len > 0) {
        if (input.charAt(ptr) == '-') {
          isNegative = true;
          ptr++;
          len--;
        } else if (input.charAt(ptr) == '+') {
          ptr++;
          len--;
        }
      }

      // ignore leading zeros
      while (len > 0 && input.charAt(ptr) == '0') {
        ptr++;
        len--;
      }

      // check decimal format and analyze precison and scale
      int valueScale = 0;
      boolean foundDot = false;
      boolean foundExponent = false;
      for (int i = 0; i < len; i++) {
        char c = input.charAt(ptr + i);
        if (Character.isDigit(c)) {
          if (foundDot) {
            valueScale++;
          }
        } else if (c == '.' && !foundDot) {
          foundDot = true;
        } else if ((c == 'e' || c == 'E') && i + 1 < len) {
          foundExponent = true;
          int exponent = Integer.parseInt(input.substring(ptr + i + 1));
          valueScale -= exponent;
          len = ptr + i;
          break;
        } else {
          throw new IllegalArgumentException("Invalid decimal format: " + input);
        }
      }

      // get result value
      String
          numberWithoutExponent =
          foundExponent ? input.substring(ptr, len) : input.substring(ptr);
      if (foundDot) {
        numberWithoutExponent = numberWithoutExponent.replace(".", "");
      }
      if (numberWithoutExponent.isEmpty()) {
        return BigInteger.ZERO;
      }
      BigInteger tmpResult = new BigInteger(numberWithoutExponent);
      if (valueScale > resultScale) {
        tmpResult = tmpResult.divide(BigInteger.TEN.pow(valueScale - resultScale));
        if (numberWithoutExponent.charAt(
            numberWithoutExponent.length() - (valueScale - resultScale)) >= '5') {
          tmpResult = tmpResult.add(BigInteger.ONE);
        }
      } else if (valueScale < resultScale) {
        tmpResult = tmpResult.multiply(BigInteger.TEN.pow(resultScale - valueScale));
      }
      if (isNegative) {
        tmpResult = tmpResult.negate();
      }

      // TODO: check overflow
      // if (tmpResult.toString().length() - (isNegative ? 1 : 0) > resultPrecision) {
      //     throw new IllegalArgumentException("Result precision overflow.");
      // }

      return tmpResult;
    }