public static boolean fastScaleUp()

in kyuubi-hive-jdbc/src/main/java/org/apache/kyuubi/jdbc/hive/common/FastHiveDecimalImpl.java [5994:6116]


  public static boolean fastScaleUp(
      long fast0, long fast1, long fast2, int scaleUp, FastHiveDecimal fastResult) {
    if (scaleUp < 1 || scaleUp >= HiveDecimal.MAX_SCALE) {
      throw new IllegalArgumentException("Expecting scaleUp > 0 and scaleUp < 38");
    }

    long result0;
    long result1;
    long result2;

    // Each range checks for overflow first, then moves digits.
    if (scaleUp < HIGHWORD_DECIMAL_DIGITS) {
      // Need to check if there are overflow digits in the high word.

      final long overflowFactor = powerOfTenTable[HIGHWORD_DECIMAL_DIGITS - scaleUp];
      if (fast2 / overflowFactor != 0) {
        return false;
      }

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

      result2 = fast2 * multiplyFactor + fast1 / divideFactor;
      result1 = (fast1 % divideFactor) * multiplyFactor + fast0 / divideFactor;
      result0 = (fast0 % divideFactor) * multiplyFactor;
    } else if (scaleUp < HIGHWORD_DECIMAL_DIGITS + LONGWORD_DECIMAL_DIGITS) {
      // High word must be zero.  Check for overflow digits in middle word.

      if (fast2 != 0) {
        return false;
      }

      final int adjustedScaleUp = scaleUp - HIGHWORD_DECIMAL_DIGITS;

      final int middleDigits = LONGWORD_DECIMAL_DIGITS - adjustedScaleUp;
      final long overflowFactor = powerOfTenTable[middleDigits];
      if (fast1 / overflowFactor != 0) {
        return false;
      }

      if (middleDigits < HIGHWORD_DECIMAL_DIGITS) {
        // Must fill high word from both middle and lower longs.

        final int highWordMoreDigits = HIGHWORD_DECIMAL_DIGITS - middleDigits;
        final long multiplyFactor = powerOfTenTable[highWordMoreDigits];

        final long divideFactor = powerOfTenTable[LONGWORD_DECIMAL_DIGITS - highWordMoreDigits];

        result2 = fast1 * multiplyFactor + fast0 / divideFactor;
        result1 = (fast0 % divideFactor) * multiplyFactor;
        result0 = 0;
      } else if (middleDigits == HIGHWORD_DECIMAL_DIGITS) {
        // Fill high long from middle long, and middle long from lower long.

        result2 = fast1;
        result1 = fast0;
        result0 = 0;
      } else {
        // Fill high long from some of middle long.

        final int keepMiddleDigits = middleDigits - HIGHWORD_DECIMAL_DIGITS;
        final long divideFactor = powerOfTenTable[keepMiddleDigits];
        final long multiplyFactor = powerOfTenTable[LONGWORD_DECIMAL_DIGITS - keepMiddleDigits];

        result2 = fast1 / divideFactor;
        result1 = (fast1 % divideFactor) * multiplyFactor + fast0 / divideFactor;
        result0 = (fast0 % divideFactor) * multiplyFactor;
      }
    } else {
      // High and middle word must be zero.  Check for overflow digits in lower word.

      if (fast2 != 0 || fast1 != 0) {
        return false;
      }

      final int adjustedScaleUp = scaleUp - HIGHWORD_DECIMAL_DIGITS - LONGWORD_DECIMAL_DIGITS;

      final int lowerDigits = LONGWORD_DECIMAL_DIGITS - adjustedScaleUp;
      final long overflowFactor = powerOfTenTable[lowerDigits];
      if (fast0 / overflowFactor != 0) {
        return false;
      }

      if (lowerDigits < HIGHWORD_DECIMAL_DIGITS) {
        // Must fill high word from both middle and lower longs.

        final int highWordMoreDigits = HIGHWORD_DECIMAL_DIGITS - lowerDigits;
        final long multiplyFactor = powerOfTenTable[highWordMoreDigits];

        final long divideFactor = powerOfTenTable[LONGWORD_DECIMAL_DIGITS - highWordMoreDigits];

        result2 = fast0 * multiplyFactor;
        result1 = 0;
        result0 = 0;
      } else if (lowerDigits == HIGHWORD_DECIMAL_DIGITS) {
        // Fill high long from lower long.

        result2 = fast0;
        result1 = 0;
        result0 = 0;
      } else {
        // Fill high long and middle from some of lower long.

        final int keepLowerDigits = lowerDigits - HIGHWORD_DECIMAL_DIGITS;
        final long keepLowerDivideFactor = powerOfTenTable[keepLowerDigits];
        final long keepLowerMultiplyFactor =
            powerOfTenTable[LONGWORD_DECIMAL_DIGITS - keepLowerDigits];

        result2 = fast0 / keepLowerDivideFactor;
        result1 = (fast0 % keepLowerDivideFactor) * keepLowerMultiplyFactor;
        result0 = 0;
      }
    }

    if (result0 == 0 && result1 == 0 && result2 == 0) {
      fastResult.fastSignum = 0;
    }
    fastResult.fast0 = result0;
    fastResult.fast1 = result1;
    fastResult.fast2 = result2;

    return true;
  }