public static boolean fastSerializationUtilsWrite(OutputStream outputStream,
      int fastSignum, long fast0, long fast1, long fast2,
      int fastIntegerDigitCount, int fastScale,
      long[] scratchLongs)
          throws IOException {

    boolean isNegative = (fastSignum == -1);

    /*
     * The sign is encoded as the least significant bit.
     *
     * We need to adjust our decimal before conversion to binary.
     *
     * Positive:
     *   Multiply by 2.
     *
     * Negative:
     *   Logic in SerializationUtils.writeBigInteger does a negate on the BigInteger. We
     *   do not have to since FastHiveDecimal stores the numbers unsigned in fast0, fast1,
     *   and fast2.  We do need to subtract one though.
     *
     *   And then multiply by 2 and add in the 1 sign bit.
     *
     *   CONSIDER: This could be combined.
     */
    long adjust0;
    long adjust1;
    long adjust2;

    if (isNegative) {

      // Subtract 1.
      long r0 = fast0 - 1;
      long r1;
      if (r0 < 0) {
        adjust0 = r0 + MULTIPLER_LONGWORD_DECIMAL;
        r1 = fast1 - 1;
      } else {
        adjust0 = r0;
        r1 = fast1;
      }
      if (r1 < 0) {
        adjust1 = r1 + MULTIPLER_LONGWORD_DECIMAL;
        adjust2 = fast2 - 1;
      } else {
        adjust1 = r1;
        adjust2 = fast2;
      }
      if (adjust2 < 0) {
        return false;
      }

      // Now multiply by 2 and add 1 sign bit.
      r0 = adjust0 * 2 + 1;
      adjust0 =
          r0 % MULTIPLER_LONGWORD_DECIMAL;
      r1 =
          adjust1 * 2
        + r0 / MULTIPLER_LONGWORD_DECIMAL;
      adjust1 =
          r1 % MULTIPLER_LONGWORD_DECIMAL;
      adjust2 =
          adjust2 * 2
        + r1 / MULTIPLER_LONGWORD_DECIMAL;

    } else {

      // Multiply by 2 to make room for 0 sign bit.
      long r0 = fast0 * 2;
      adjust0 =
          r0 % MULTIPLER_LONGWORD_DECIMAL;
      final long r1 =
          fast1 * 2
        + r0 / MULTIPLER_LONGWORD_DECIMAL;
      adjust1 =
          r1 % MULTIPLER_LONGWORD_DECIMAL;
      adjust2 =
          fast2 * 2
        + r1 / MULTIPLER_LONGWORD_DECIMAL;

    }

    /*
     * Use common decimal to binary conversion method we share with fastBigIntegerBytes.
     */
    if (!doDecimalToBinaryConversion(
        adjust0, adjust1, adjust2,
        FAST_HIVE_DECIMAL_TWO_POWER_63_INVERSE,
        SERIALIZATION_UTILS_WRITE_QUOTIENT_INTEGER_WORD_NUM,
        SERIALIZATION_UTILS_WRITE_QUOTIENT_INTEGER_DIGIT_NUM,
        FAST_HIVE_DECIMAL_TWO_POWER_63,
        scratchLongs)) {
      // Overflow.
      return false;
    }

    long lowerWord63 = scratchLongs[0];
    long middleWord63 = scratchLongs[1];
    long highWord63 = scratchLongs[2];

    int wordCount;
    if (highWord63 != 0) {
      wordCount = 3;
    } else if (middleWord63 != 0) {
      wordCount = 2;
    } else {
      wordCount = 1;
    }

    // Write out the first 63 bits worth of data.
    long lowBits = lowerWord63;
    for(int i=0; i < 9; ++i) {
      // If this is the last byte, leave the high bit off
      if (wordCount == 1 && (lowBits & ~0x7f) == 0) {
        outputStream.write((byte) lowBits);
        return true;
      } else {
        outputStream.write((byte) (0x80 | (lowBits & 0x7f)));
        lowBits >>>= 7;
      }
    }
    if (wordCount <= 1) {
      throw new RuntimeException("Expecting write word count > 1");
    }

    lowBits = middleWord63;
    for(int i=0; i < 9; ++i) {
      // If this is the last byte, leave the high bit off
      if (wordCount == 2 && (lowBits & ~0x7f) == 0) {
        outputStream.write((byte) lowBits);
        return true;
      } else {
        outputStream.write((byte) (0x80 | (lowBits & 0x7f)));
        lowBits >>>= 7;
      }
    }

    lowBits = highWord63;
    for(int i=0; i < 9; ++i) {
      // If this is the last byte, leave the high bit off
      if ((lowBits & ~0x7f) == 0) {
        outputStream.write((byte) lowBits);
        return true;
      } else {
        outputStream.write((byte) (0x80 | (lowBits & 0x7f)));
        lowBits >>>= 7;
      }
    }

    // Should not get here.
    throw new RuntimeException("Unexpected");
  }
*********************************************************************************************
  // Emulate SerializationUtils Serialization used by ORC.

  /**
Write the value of this decimal just like SerializationUtils.writeBigInteger.  It header
comments are:

    Write the arbitrarily sized signed BigInteger in vint format.

    Signed integers are encoded using the low bit as the sign bit using zigzag
    encoding.

    Each byte uses the low 7 bits for data and the high bit for stop/continue.

    Bytes are stored LSB first.

NOTE:
   SerializationUtils.writeBigInteger sometimes pads the result with extra zeroes due to
   BigInteger.bitLength -- we do not emulate that.  SerializationUtils.readBigInteger will
   produce the same result for both.

@param outputStream the stream to write to
@param fastSignum the sign digit (-1, 0, or +1)
@param fast0 word 0 of the internal representation
@param fast1 word 1 of the internal representation
@param fast2 word 2 of the internal representation
@param fastIntegerDigitCount unused
@param fastScale unused
@param scratchLongs scratch space
@return True if the decimal was successfully serialized into the output stream.
@throws IOException for problems in writing
storage-api/src/java/org/apache/hadoop/hive/common/type/FastHiveDecimalImpl.java