public static boolean doFastRound(
      int fastSignum, long fast0, long fast1, long fast2,
      int fastIntegerDigitCount, int fastScale,
      int roundPower,
      int roundingMode,
      FastHiveDecimal fastResult) {

    if (fastSignum == 0) {

      // Zero result.
      fastResult.fastReset();
      return true;
    } else if (fastScale == roundPower) {

      // The roundPower same as scale means all zeroes below round point.

      fastResult.fastSet(fastSignum, fast0, fast1, fast2, fastIntegerDigitCount, fastScale);
      /*
      if (!fastResult.fastIsValid()) {
        fastResult.fastRaiseInvalidException();
      }
      */
      return true;
    }

    if (roundPower > fastScale) {

      // We pretend to add trailing zeroes, EVEN WHEN it would exceed the HiveDecimal.MAX_PRECISION.

      // Copy current value; do not change current scale.
      fastResult.fastSet(fastSignum, fast0, fast1, fast2, fastIntegerDigitCount, fastScale);
      /*
      if (!fastResult.fastIsValid()) {
        fastResult.fastRaiseInvalidException();
      }
      */
    } else if (roundPower < 0) {

      // roundPower < 0
      //
      // Negative scale means we start rounding integer digits.
      //
      // The result will integer result will have at least abs(roundPower) trailing digits.
      //
      // Examples where the 'r's show the rounding digits:
      //
      //      round(12500, -3) = 13000           // BigDecimal.ROUND_HALF_UP
      //              rrr
      //
      // Or,  ceiling(12400.8302, -2) = 12500     // BigDecimal.ROUND_CEILING
      //                 rr rrrr
      //
      // Notice that any fractional digits will be gone in the result.
      //
     switch (roundingMode) {
      case BigDecimal.ROUND_DOWN:
        if (!fastRoundIntegerDown(
            fastSignum, fast0, fast1, fast2,
            fastIntegerDigitCount, fastScale,
            roundPower,
            fastResult)) {
          return false;
        }
        break;
      case BigDecimal.ROUND_UP:
        if (!fastRoundIntegerUp(
            fastSignum, fast0, fast1, fast2,
            fastIntegerDigitCount, fastScale,
            roundPower,
            fastResult)) {
          return false;
        }
        break;
      case BigDecimal.ROUND_FLOOR:
        // Round towards negative infinity.
        if (fastSignum == 1) {
          if (!fastRoundIntegerDown(
              fastSignum, fast0, fast1, fast2,
              fastIntegerDigitCount, fastScale,
              roundPower,
              fastResult)) {
            return false;
          }
        } else {
          if (!fastRoundIntegerUp(
              fastSignum, fast0, fast1, fast2,
              fastIntegerDigitCount, fastScale,
              roundPower,
              fastResult)) {
            return false;
          }
          if (fastResult.fast2 > MAX_HIGHWORD_DECIMAL) {
            return false;
          }
        }
        break;
      case BigDecimal.ROUND_CEILING:
        // Round towards positive infinity.
        if (fastSignum == 1) {
          if (!fastRoundIntegerUp(
              fastSignum, fast0, fast1, fast2,
              fastIntegerDigitCount, fastScale,
              roundPower,
              fastResult)) {
            return false;
          }
          if (fastResult.fast2 > MAX_HIGHWORD_DECIMAL) {
            return false;
          }
        } else {
          if (!fastRoundIntegerDown(
              fastSignum, fast0, fast1, fast2,
              fastIntegerDigitCount, fastScale,
              roundPower,
              fastResult)) {
            return false;
          }
        }
        break;
      case BigDecimal.ROUND_HALF_UP:
        if (!fastRoundIntegerHalfUp(
            fastSignum, fast0, fast1, fast2,
            fastIntegerDigitCount, fastScale,
            roundPower,
            fastResult)) {
          return false;
        }
        if (fastResult.fast2 > MAX_HIGHWORD_DECIMAL) {
          return false;
        }
        break;
      case BigDecimal.ROUND_HALF_EVEN:
        if (!fastRoundIntegerHalfEven(
            fastSignum, fast0, fast1, fast2,
            fastIntegerDigitCount, fastScale,
            roundPower,
            fastResult)) {
          return false;
        }
        if (fastResult.fast2 > MAX_HIGHWORD_DECIMAL) {
          return false;
        }
        break;
      default:
        throw new RuntimeException("Unsupported rounding mode " + roundingMode);
      }

      // The fastRoundInteger* methods remove all fractional digits, set fastIntegerDigitCount, and
      // set fastScale to 0.
      return true;

    } else {

      // roundPower < fastScale

      // Do rounding of fractional digits.
      final int scaleDown = fastScale - roundPower;
      switch (roundingMode) {
      case BigDecimal.ROUND_DOWN:
        fastRoundFractionalDown(
            fastSignum, fast0, fast1, fast2,
            scaleDown,
            fastResult);
        break;
      case BigDecimal.ROUND_UP:
        if (!fastRoundFractionalUp(
            fastSignum, fast0, fast1, fast2,
            scaleDown,
            fastResult)) {
          return false;
        }
        break;
      case BigDecimal.ROUND_FLOOR:
        // Round towards negative infinity.
        if (fastSignum == 1) {
          fastRoundFractionalDown(
              fastSignum, fast0, fast1, fast2,
              scaleDown,
              fastResult);
        } else {
          if (!fastRoundFractionalUp(
              fastSignum, fast0, fast1, fast2,
              scaleDown,
              fastResult)) {
            return false;
          }
        }
        break;
      case BigDecimal.ROUND_CEILING:
        // Round towards positive infinity.
        if (fastSignum == 1) {
          if (!fastRoundFractionalUp(
              fastSignum, fast0, fast1, fast2,
              scaleDown,
              fastResult)) {
            return false;
          }
        } else {
          fastRoundFractionalDown(
              fastSignum, fast0, fast1, fast2,
              scaleDown,
              fastResult);
        }
        break;
      case BigDecimal.ROUND_HALF_UP:
        if (!fastRoundFractionalHalfUp(
            fastSignum, fast0, fast1, fast2,
            scaleDown,
            fastResult)) {
          return false;
        }
        break;
      case BigDecimal.ROUND_HALF_EVEN:
        if (!fastRoundFractionalHalfEven(
            fastSignum, fast0, fast1, fast2,
            scaleDown,
            fastResult)) {
          return false;
        }
        break;
      default:
        throw new RuntimeException("Unsupported rounding mode " + roundingMode);
      }
      if (fastResult.fastSignum == 0) {
        fastResult.fastScale = 0;
        /*
        if (!fastResult.fastIsValid()) {
          fastResult.fastRaiseInvalidException();
        }
        */
      } else {
        final int rawPrecision = fastRawPrecision(fastResult);
        fastResult.fastIntegerDigitCount = Math.max(0, rawPrecision - roundPower);
        fastResult.fastScale = roundPower;

        // Trim trailing zeroes and re-adjust scale.
        final int trailingZeroCount =
            fastTrailingDecimalZeroCount(
                fastResult.fast0, fastResult.fast1, fastResult.fast2,
                fastResult.fastIntegerDigitCount, fastResult.fastScale);
        if (trailingZeroCount > 0) {
          doFastScaleDown(
              fastResult,
              trailingZeroCount,
              fastResult);
          fastResult.fastScale -= trailingZeroCount;
          /*
          if (!fastResult.fastIsValid()) {
            fastResult.fastRaiseInvalidException();
          }
          */
        }
      }
    }

    return true;
  }
*********************************************************************************************
  // Decimal Math.

  public static boolean fastScaleByPowerOfTen(
      FastHiveDecimal fastDec,
      int power,
      FastHiveDecimal fastResult) {
    return fastScaleByPowerOfTen(
        fastDec.fastSignum, fastDec.fast0, fastDec.fast1, fastDec.fast2,
        fastDec.fastIntegerDigitCount, fastDec.fastScale,
        power,
        fastResult);
  }

  // NOTE: power can be positive or negative.
  // NOTE: e.g. power = 2 is effectively multiply by 10^2
  // NOTE:      and power = -3 is multiply by 10^-3
  public static boolean fastScaleByPowerOfTen(
      int fastSignum, long fast0, long fast1, long fast2,
      int fastIntegerDigitCount, int fastScale,
      int power,
      FastHiveDecimal fastResult) {

    if (fastSignum == 0) {
      fastResult.fastReset();
      return true;
    }
    if (power == 0) {
      fastResult.fastSet(fastSignum, fast0, fast1, fast2, fastIntegerDigitCount, fastScale);
      /*
      if (!fastResult.fastIsValid()) {
        fastResult.fastRaiseInvalidException();
      }
storage-api/src/java/org/apache/hadoop/hive/common/type/FastHiveDecimalImpl.java