private static boolean doFinishAddSubtractDifferentScale(
      long result0, long result1, long result2, long result3, long result4,
      int resultScale,
      FastHiveDecimal fastResult) {

    int precision;
    if (result4 != 0) {
      precision = FOUR_X_LONGWORD_DECIMAL_DIGITS + fastLongWordPrecision(result4);
    } else if (result3 != 0) {
      precision = THREE_X_LONGWORD_DECIMAL_DIGITS + fastLongWordPrecision(result3);
    } else if (result2 != 0) {
      precision = TWO_X_LONGWORD_DECIMAL_DIGITS + fastLongWordPrecision(result2);
    } else if (result1 != 0) {
      precision = LONGWORD_DECIMAL_DIGITS + fastLongWordPrecision(result1);
    } else {
      precision = fastLongWordPrecision(result0);
    }

    if (precision > HiveDecimal.MAX_PRECISION){
      final int scaleDown = precision - HiveDecimal.MAX_PRECISION;

      resultScale -= scaleDown;
      if (resultScale < 0) {
        // No room.
        return false;
      }
      if (!fastRoundFractionalHalfUp5Words(
            1, result0, result1, result2, result3, result4,
            scaleDown,
            fastResult)) {
        // Handle overflow precision issue.
        if (resultScale > 0) {
          if (!fastRoundFractionalHalfUp(
              fastResult.fastSignum, fastResult.fast0, fastResult.fast1, fastResult.fast2,
              1,
              fastResult)) {
            throw new RuntimeException("Unexpected overflow");
          }
          if (fastResult.fastSignum == 0) {
            return true;
          }
          resultScale--;
        } else {
          return false;
        }
      }

      precision = fastRawPrecision(1, fastResult.fast0, fastResult.fast1, fastResult.fast2);

      // Stick back into result variables...
      result0 = fastResult.fast0;
      result1 = fastResult.fast1;
      result2 = fastResult.fast2;
    }

    // Caller will set signum.
    fastResult.fastSignum = 1;
    fastResult.fast0 = result0;
    fastResult.fast1 = result1;
    fastResult.fast2 = result2;
    fastResult.fastIntegerDigitCount = Math.max(0, precision - resultScale);
    fastResult.fastScale = resultScale;

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

    return true;
  }
Handle the common logic at the end of fastAddDifferentScale / fastSubtractDifferentScale that
takes the 5 intermediate result words and fits them into the 3 longword fast result.
storage-api/src/java/org/apache/hadoop/hive/common/type/FastHiveDecimalImpl.java