public static boolean fastSetFromDigitsOnlyBytesAndScale(
      boolean isNegative, byte[] bytes, int offset, int length, int scale,
      FastHiveDecimal fastResult) {

    final int bytesLength = bytes.length;

    if (offset < 0 || offset >= bytesLength) {
      return false;
    }
    final int end = offset + length;
    if (end <= offset || end > bytesLength) {
      return false;
    }

    // We start here with at least one byte.
    int index = offset;

    // A stripped down version of fastSetFromBytes.

    int precision = 0;

    // We fill starting with highest digit in highest longword (HIGHWORD_DECIMAL_DIGITS) and
    // move down.  At end will will shift everything down if necessary.

    int longWordIndex = 0;   // Where 0 is the highest longword; 1 is middle longword, etc.

    int digitNum = HIGHWORD_DECIMAL_DIGITS;
    long multiplier = powerOfTenTable[HIGHWORD_DECIMAL_DIGITS - 1];

    int digitValue;
    long longWord = 0;

    long fast0 = 0;
    long fast1 = 0;
    long fast2 = 0;

    byte work;

    // Parse digits.

    boolean haveInteger = false;
    while (true) {
      work = bytes[index];
      if (work < BYTE_DIGIT_ZERO || work > BYTE_DIGIT_NINE) {
        if (!haveInteger) {
          return false;
        }
        break;
      }
      haveInteger = true;
      if (precision == 0 && work == BYTE_DIGIT_ZERO) {
        // Ignore leading zeroes.
        if (++index >= end) {
          break;
        }
        continue;
      }
      digitValue = work - BYTE_DIGIT_ZERO;
      if (digitNum == 0) {

        // Integer parsing move to next lower longword.

        // Save previous longword.
        if (longWordIndex == 0) {
          fast2 = longWord;
        } else if (longWordIndex == 1) {
          fast1 = longWord;
        } else if (longWordIndex == 2) {

          // We have filled HiveDecimal.MAX_PRECISION digits and have no more room in our limit precision
          // fast decimal.
          return false;
        }
        longWordIndex++;

        // The middle and lowest longwords highest digit number is LONGWORD_DECIMAL_DIGITS.
        digitNum = LONGWORD_DECIMAL_DIGITS;
        multiplier = powerOfTenTable[LONGWORD_DECIMAL_DIGITS - 1];
        longWord = 0;
      }
      longWord += digitValue * multiplier;
      multiplier /= 10;
      digitNum--;
      precision++;
      if (++index >= end) {
        break;
      }
    }

    // Just an digits?
    if (index < end) {
      return false;
    }

    if (precision == 0) {
      // We just had leading zeroes.
      // Value is 0.
      return true;
    }

    // Save last longword.
    if (longWordIndex == 0) {
      fast2 = longWord;
    } else if (longWordIndex == 1) {
      fast1 = longWord;
    } else {
      fast0 = longWord;
    }
    fastResult.fastSignum = (isNegative ? -1 : 1);
    fastResult.fastIntegerDigitCount = Math.max(0, precision - scale);
    fastResult.fastScale = scale;
    final int scaleDown = HiveDecimal.MAX_PRECISION - precision;
    if (scaleDown > 0) {
      doFastScaleDown(fast0, fast1, fast2, scaleDown, fastResult);
    } else {
      fastResult.fast0 = fast0;
      fastResult.fast1 = fast1;
      fastResult.fast2 = fast2;
    }
    return true;

  }
Scans a byte array slice for UNSIGNED RAW DIGITS ONLY in UTF-8 (ASCII) characters
and forms a decimal from the digits and a sign and scale.

Designed for BinarySortable serialization format that separates the sign and scale
from the raw digits.

NOTE: The fastSetFromDigitsOnlyBytesAndScale method requires the caller to pass a fastResult
parameter has been reset for better performance.

@param isNegative is the number negative
@param bytes the bytes to read from
@param offset the position to start at
@param length the number of bytes to read
@param scale the scale of the number
@param fastResult an object it into
@return True if the sign, digits, and scale were successfully converted to a decimal.
storage-api/src/java/org/apache/hadoop/hive/common/type/FastHiveDecimalImpl.java