public static boolean fastScaleDownNoRound(
      int fastSignum, long fast0, long fast1, long fast2,
      int scaleDown,
      FastHiveDecimal fastResult) {
    if (scaleDown < 1 || scaleDown >= THREE_X_LONGWORD_DECIMAL_DIGITS - 1) {
      throw new IllegalArgumentException("Expecting scaleDown > 0 and scaleDown < 3*16 - 1 (scaleDown " + scaleDown + ")");
    }

    // Adjust all longs using power 10 division/remainder.
    long result0;
    long result1;
    long result2;
    if (scaleDown < LONGWORD_DECIMAL_DIGITS) {

      // Part of lowest word survives.

      final long divideFactor = powerOfTenTable[scaleDown];
      final long multiplyFactor = powerOfTenTable[LONGWORD_DECIMAL_DIGITS - scaleDown];

      final long throwAwayFraction = fast0 % divideFactor;

      if (throwAwayFraction != 0) {
        return false;
      }
      result0 =
          fast0 / divideFactor
        + ((fast1 % divideFactor) * multiplyFactor);
      result1 =
          fast1 / divideFactor
        + ((fast2 % divideFactor) * multiplyFactor);
      result2 =
          fast2 / divideFactor;

    } else if (scaleDown < TWO_X_LONGWORD_DECIMAL_DIGITS) {

      // Throw away lowest word.

      final int adjustedScaleDown = scaleDown - LONGWORD_DECIMAL_DIGITS;

      final long divideFactor = powerOfTenTable[adjustedScaleDown];
      final long multiplyFactor = powerOfTenTable[LONGWORD_DECIMAL_DIGITS - adjustedScaleDown];

      boolean isThrowAwayFractionZero;
      if (adjustedScaleDown == 0) {
        isThrowAwayFractionZero = (fast0 == 0);
      } else {
        final long throwAwayFraction = fast1 % divideFactor;
        isThrowAwayFractionZero = (throwAwayFraction == 0 && fast0 == 0);
      }

      if (!isThrowAwayFractionZero) {
        return false;
      }
      result0 =
          fast1 / divideFactor
        + ((fast2 % divideFactor) * multiplyFactor);
      result1 =
          fast2 / divideFactor;
      result2 = 0;

    } else {

      // Throw away middle and lowest words.

      final int adjustedScaleDown = scaleDown - 2*LONGWORD_DECIMAL_DIGITS;

      final long divideFactor = powerOfTenTable[adjustedScaleDown];

      boolean isThrowAwayFractionZero;
      if (adjustedScaleDown == 0) {
        isThrowAwayFractionZero = (fast0 == 0 && fast1 == 0);
      } else {
        final long throwAwayFraction = fast2 % divideFactor;
        isThrowAwayFractionZero = (throwAwayFraction == 0 && fast0 == 0 && fast1 == 0);
      }

      if (!isThrowAwayFractionZero) {
        return false;
      }
      result0 =
          fast2 / divideFactor;
      result1 = 0;
      result2 = 0;
    }

    if (result0 == 0 && result1 == 0 && result2 == 0) {
      fastResult.fastReset();
    } else {
      fastResult.fastSignum = fastSignum;
      fastResult.fast0 = result0;
      fastResult.fast1 = result1;
      fastResult.fast2 = result2;
    }

    return true;
  }
Fast decimal scale down by factor of 10 and do not allow rounding.

When the fraction being scaled away is non-zero, return false.

The signum will be updated if the result is 0, otherwise the original sign
is unchanged.

@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 scaleDown the digits to scale down by
@param fastResult an object to reuse
@return was the operation successful?
storage-api/src/java/org/apache/hadoop/hive/common/type/FastHiveDecimalImpl.java