public static boolean fastSetFromBigIntegerBytesAndScale(
      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;
    }

    final int startOffset = offset;

    // Roughly based on BigInteger code.

    boolean isNegative = (bytes[offset] < 0);
    if (isNegative) {

      // Find first non-sign (0xff) byte of input.
      while (offset < end) {
        if (bytes[offset] != -1) {
          break;
        }
        offset++;
      }
      if (offset > end) {
        return false;
      }
    } else {

      // Strip leading zeroes -- although there shouldn't be any for a decimal.

      while (offset < end && bytes[offset] == 0) {
        offset++;
      }
      if (offset >= end) {
        // Zero.
        return true;
      }
    }

    long lowerWord56 = 0;
    long middleWord56 = 0;
    long highWord56 = 0;

    int reverseIndex = end;

    long work;
    int shift;

    final int lowestCount = Math.min(reverseIndex - offset, 7);
    shift = 0;
    for (int i = 0; i < lowestCount; i++) {
      work = bytes[--reverseIndex] & 0xFF;
      lowerWord56 |= work << shift;
      shift += 8;
    }

    if (reverseIndex <= offset) {
      if (isNegative) {
        lowerWord56 = ~lowerWord56 & ((1L << shift) - 1);
      }
    } else {

      // Go on to middle word.

      final int middleCount = Math.min(reverseIndex - offset, 7);
      shift = 0;
      for (int i = 0; i < middleCount; i++) {
        work = bytes[--reverseIndex] & 0xFF;
        middleWord56 |= work << shift;
        shift += 8;
      }
      if (reverseIndex <= offset) {
        if (isNegative) {
          lowerWord56 = ~lowerWord56 & LONG_56_BIT_MASK;
          middleWord56 = ~middleWord56 & ((1L << shift) - 1);
        }
      } else {

        // Go on to high word.

        final int highCount = Math.min(reverseIndex - offset, 7);
        shift = 0;
        for (int i = 0; i < highCount; i++) {
          work = bytes[--reverseIndex] & 0xFF;
          highWord56 |= work << shift;
          shift += 8;
        }
        if (isNegative) {
          // We only need to apply negation to all 3 words when there are 3 words, etc.
          lowerWord56 = ~lowerWord56 & LONG_56_BIT_MASK;
          middleWord56 = ~middleWord56 & LONG_56_BIT_MASK;
          highWord56 = ~highWord56 & ((1L << shift) - 1);
        }
      }
    }

    if (!doBinaryToDecimalConversion(
          lowerWord56, middleWord56, highWord56,
          FAST_HIVE_DECIMAL_TWO_POWER_56,
          FAST_HIVE_DECIMAL_TWO_POWER_112,    // 2^(56 + 56)
          fastResult)) {
      // Overflow.  Use slower alternate.
      return doAlternateSetFromBigIntegerBytesAndScale(
          bytes, startOffset, length, scale,
          fastResult);
    }

    // System.out.println("fastSetFromBigIntegerBytesAndScale fast0 " + fastResult.fast0 + " fast1 " + fastResult.fast1 + " fast2 " + fastResult.fast2);
    if (isNegative) {
      if (!doAddSameScaleSameSign(
          /* resultSignum */ 1,
          fastResult.fast0, fastResult.fast1, fastResult.fast2,
          1, 0, 0,
          fastResult)) {
        // Overflow.  Use slower alternate.
        return doAlternateSetFromBigIntegerBytesAndScale(
            bytes, startOffset, length, scale,
            fastResult);
      }
    }

    if (fastResult.fast0 == 0 && fastResult.fast1 == 0 && fastResult.fast2 == 0) {
      fastResult.fastSignum = 0;
    } else {
      fastResult.fastSignum = (isNegative ? -1 : 1);
      fastResult.fastScale = scale;
      final int rawPrecision = fastRawPrecision(fastResult);
      fastResult.fastIntegerDigitCount = Math.max(0, rawPrecision - scale);

      /*
       * Just in case we deserialize a decimal with trailing zeroes...
       */
      final int resultTrailingZeroCount =
          fastTrailingDecimalZeroCount(
              fastResult.fast0, fastResult.fast1, fastResult.fast2,
              fastResult.fastIntegerDigitCount, fastResult.fastScale);
      if (resultTrailingZeroCount > 0) {
        doFastScaleDown(
            fastResult,
            resultTrailingZeroCount,
            fastResult);

        fastResult.fastScale -= resultTrailingZeroCount;
      }
    }

    return true;
  }
Convert bytes in the format used by BigInteger's toByteArray format (and accepted by its
constructor) into a decimal using the specified scale.

Our bigIntegerBytes methods create bytes in this format, too.

This method is designed for high performance and does not create an actual BigInteger during
binary to decimal conversion.

@param bytes the bytes to read from
@param offset the starting position in the bytes array
@param length the number of bytes to read from the bytes array
@param scale the scale of the number
@param fastResult an object to reused
@return did the conversion succeed?
storage-api/src/java/org/apache/hadoop/hive/common/type/FastHiveDecimalImpl.java