public static long fastLongValueClip(
      int fastSignum, long fast0, long fast1, long fast2,
      int fastIntegerDigitCount, int fastScale) {
    if (fastSignum == 0) {
      return 0;
    }

    if (fastScale == 0) {
      // Do first comparison as unsigned.
      if (fastCompareTo(
          1, fast0, fast1, fast2, fastScale,
          FASTHIVEDECIMAL_MAX_LONG_VALUE) <= 0) {
        if (fastSignum == 1) {
          return
              fast1 * MULTIPLER_LONGWORD_DECIMAL
            + fast0;
        } else {
          return
             -(fast1 * MULTIPLER_LONGWORD_DECIMAL
             + fast0);
        }
      } if (fastEquals(
          fastSignum, fast0, fast1, fast2, fastScale,
          FASTHIVEDECIMAL_MIN_LONG_VALUE)) {
        return Long.MIN_VALUE;
      } else {
        // SLOW: Do remainder with BigInteger.
        BigInteger bigInteger =
            fastBigIntegerValueUnscaled(
                fastSignum, fast0, fast1, fast2);
        return bigInteger.remainder(BIG_INTEGER_UNSIGNED_LONG_MAX_VALUE).longValue();
      }
    } else {

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

        // Part of lowest word survives.

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

        result0 =
            fast0 / divideFactor
          + ((fast1 % divideFactor) * multiplyFactor);
        result1 =
            fast1 / divideFactor
          + ((fast2 % divideFactor) * multiplyFactor);
        result2 =
            fast2 / divideFactor;

      } else if (fastScale < TWO_X_LONGWORD_DECIMAL_DIGITS) {

        // Throw away lowest word.

        final int adjustedScaleDown = fastScale - LONGWORD_DECIMAL_DIGITS;

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

        result0 =
            fast1 / divideFactor
          + ((fast2 % divideFactor) * multiplyFactor);
        result1 =
            fast2 / divideFactor;
        result2 = 0;

      } else {

        // Throw away middle and lowest words.

        final int adjustedScaleDown = fastScale - 2*LONGWORD_DECIMAL_DIGITS;

        result0 =
            fast2 / powerOfTenTable[adjustedScaleDown];
        result1 = 0;
        result2 = 0;

      }

      // Do first comparison as UNSIGNED.
      if (fastCompareTo(
          1, result0, result1, result2, /* fastScale */ 0,
          FASTHIVEDECIMAL_MAX_LONG_VALUE) <= 0) {
        if (fastSignum == 1) {
          return
              result1 * MULTIPLER_LONGWORD_DECIMAL
            + result0;
        } else {
          return
             -(result1 * MULTIPLER_LONGWORD_DECIMAL
             + result0);
        }
      } if (fastEquals(
          fastSignum, result0, result1, result2, /* fastScale */ 0,
          FASTHIVEDECIMAL_MIN_LONG_VALUE)) {

        // SIGNED comparison to Long.MIN_VALUE decimal.
        return Long.MIN_VALUE;
      } else {
        // SLOW: Do remainder with BigInteger.
        BigInteger bigInteger =
            fastBigIntegerValueUnscaled(
                fastSignum, result0, result1, result2);
        return bigInteger.remainder(BIG_INTEGER_UNSIGNED_LONG_MAX_VALUE).longValue();
      }
    }
  }
Is the decimal value a long? Range -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807.
                                   Long.MIN_VALUE                Long.MAX_VALUE

Emulates testing for no value corruption:
     bigDecimalValue().setScale(0).equals(BigDecimal.valueOf(bigDecimalValue().longValue()))

NOTE: Fractional digits are ignored in the test since fastLongValueClip() will
      remove them (round down).

@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 True when fastLongValueClip() will return a correct long.
storage-api/src/java/org/apache/hadoop/hive/common/type/FastHiveDecimalImpl.java