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();
      }
      */
      return true;
    }

    final int absPower = Math.abs(power);

    if (power > 0) {

      int integerRoom;
      int fractionalRoom;
      if (fastIntegerDigitCount > 0) {

        // Is there integer room above?

        integerRoom = HiveDecimal.MAX_PRECISION - fastIntegerDigitCount;
        if (integerRoom < power) {
          return false;
        }
        fastResult.fastSignum = fastSignum;
        if (fastScale <= power) {

          // All fractional digits become integer digits.
          final int scaleUp = power - fastScale;
          if (scaleUp > 0) {
            if (!fastScaleUp(
                fast0, fast1, fast2,
                scaleUp,
                fastResult)) {
              throw new RuntimeException("Unexpected");
            }
          } else {
            fastResult.fast0 = fast0;
            fastResult.fast1 = fast1;
            fastResult.fast2 = fast2;
          }
          fastResult.fastIntegerDigitCount = fastIntegerDigitCount + fastScale + scaleUp;
          fastResult.fastScale = 0;

        } else {

          // Only a scale adjustment is needed.
          fastResult.fastSet(
              fastSignum, fast0, fast1, fast2,
              fastIntegerDigitCount + power, fastScale - power);
        }
      } else {

        // How much can the fraction be moved up?

        final int rawPrecision = fastRawPrecision(fastSignum, fast0, fast1, fast2);
        final int zeroesBelowDot = fastScale - rawPrecision;

        // Our limit is max precision integer digits + "leading" zeros below the dot.
        // E.g. 0.00021 has 3 zeroes below the dot.
        //
        if (power > HiveDecimal.MAX_PRECISION + zeroesBelowDot) {

          // Fractional part powered up too high.
          return false;
        }

        final int newIntegerDigitCount = Math.max(0, power - zeroesBelowDot);
        if (newIntegerDigitCount > rawPrecision) {

          fastResult.fastSignum = fastSignum;
          final int scaleUp = newIntegerDigitCount - rawPrecision;
          if (!fastScaleUp(
              fast0, fast1, fast2,
              scaleUp,
              fastResult)) {
            throw new RuntimeException("Unexpected");
          }
          fastResult.fastIntegerDigitCount = newIntegerDigitCount;
          fastResult.fastScale = 0;
        } else {
          final int newScale = Math.max(0, fastScale - power);
          fastResult.fastSet(fastSignum, fast0, fast1, fast2, newIntegerDigitCount, newScale);
        }
      }

    } else if (fastScale + absPower <= HiveDecimal.MAX_SCALE) {

      // Negative power with range -- adjust the scale.

      final int newScale = fastScale + absPower;
      final int newIntegerDigitCount = Math.max(0, fastIntegerDigitCount - absPower);

      final int trailingZeroCount =
          fastTrailingDecimalZeroCount(
              fast0, fast1, fast2,
              newIntegerDigitCount, newScale);
      if (trailingZeroCount > 0) {
        fastResult.fastSignum = fastSignum;
        doFastScaleDown(
            fast0, fast1, fast2,
            trailingZeroCount, fastResult);
        fastResult.fastScale = newScale - trailingZeroCount;
        fastResult.fastIntegerDigitCount = newIntegerDigitCount;
      } else {
        fastResult.fastSet(fastSignum, fast0, fast1, fast2,
            newIntegerDigitCount, newScale);
      }
    } else {

      // fastScale + absPower > HiveDecimal.MAX_SCALE

      // Look at getting rid of fractional digits that will now be below HiveDecimal.MAX_SCALE.

      final int scaleDown = fastScale + absPower - HiveDecimal.MAX_SCALE;

      if (scaleDown < HiveDecimal.MAX_SCALE) {
        if (!fastRoundFractionalHalfUp(
            fastSignum, fast0, fast1, fast2,
            scaleDown,
            fastResult)) {
          // Overflow.
          return false;
        }
        if (fastResult.fastSignum != 0) {

          fastResult.fastScale = HiveDecimal.MAX_SCALE;
          fastResult.fastIntegerDigitCount =
              Math.max(0, fastRawPrecision(fastResult) - fastResult.fastScale);

          final int trailingZeroCount =
              fastTrailingDecimalZeroCount(
                  fastResult.fast0, fastResult.fast1, fastResult.fast2,
                  fastResult.fastIntegerDigitCount, fastResult.fastScale);
          if (trailingZeroCount > 0) {
            doFastScaleDown(
                fastResult,
                trailingZeroCount,
                fastResult);
            fastResult.fastScale -= trailingZeroCount;
          }
        }
      } else {
        // All precision has been lost -- result is 0.
        fastResult.fastReset();
      }
    }

    /*
    if (!fastResult.fastIsValid()) {
      fastResult.fastRaiseInvalidException();
    }
    */

    return true;
  }
This is the original hash code as returned by OldHiveDecimal.

We need this when the OldHiveDecimal hash code has been exposed and and written or affected
how data is written.

This method supports compatibility.

Examples: bucketing and the Hive hash() function.

NOTE: It is necessary to create a BigDecimal object and use its hash code, so this method is
      slow.

@param fastSignum the sign (-1, 0, or +1)
@param fast0 word 0 of the internal representation
@param fast1 word 1
@param fast2 word 2
@param fastIntegerDigitCount the number of integer digits
@param fastScale the scale of the number
@return the hash code
storage-api/src/java/org/apache/hadoop/hive/common/type/FastHiveDecimalImpl.java