private static boolean fastAddDifferentScale()

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


  private static boolean fastAddDifferentScale(
      long leftFast0,
      long leftFast1,
      long leftFast2,
      int leftIntegerDigitCount,
      int leftScale,
      long rightFast0,
      long rightFast1,
      long rightFast2,
      int rightIntegerDigitCount,
      int rightScale,
      FastHiveDecimal fastResult) {

    // Arrange so result* has a longer digit tail and it lines up; we will shift the shift* digits
    // as we do our addition and them into the result.
    long result0;
    long result1;
    long result2;

    long shift0;
    long shift1;
    long shift2;

    int diffScale;
    int resultScale;

    // Since addition is commutative, we can add in any order.
    if (leftScale > rightScale) {

      result0 = leftFast0;
      result1 = leftFast1;
      result2 = leftFast2;

      shift0 = rightFast0;
      shift1 = rightFast1;
      shift2 = rightFast2;

      diffScale = leftScale - rightScale;
      resultScale = leftScale;
    } else {

      result0 = rightFast0;
      result1 = rightFast1;
      result2 = rightFast2;

      shift0 = leftFast0;
      shift1 = leftFast1;
      shift2 = leftFast2;

      diffScale = rightScale - leftScale;
      resultScale = rightScale;
    }

    long result3 = 0;
    long result4 = 0;

    if (diffScale < LONGWORD_DECIMAL_DIGITS) {

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

      final long r0 = result0 + (shift0 % divideFactor) * multiplyFactor;
      result0 = r0 % MULTIPLER_LONGWORD_DECIMAL;
      final long r1 =
          result1
              + shift0 / divideFactor
              + (shift1 % divideFactor) * multiplyFactor
              + r0 / MULTIPLER_LONGWORD_DECIMAL;
      result1 = r1 % MULTIPLER_LONGWORD_DECIMAL;
      final long r2 =
          result2
              + shift1 / divideFactor
              + (shift2 % divideFactor) * multiplyFactor
              + r1 / MULTIPLER_LONGWORD_DECIMAL;
      result2 = r2 % MULTIPLER_LONGWORD_DECIMAL;
      final long r3 = shift2 / divideFactor + r2 / MULTIPLER_LONGWORD_DECIMAL;
      result3 = r3 % MULTIPLER_LONGWORD_DECIMAL;

    } else if (diffScale == LONGWORD_DECIMAL_DIGITS) {

      final long r1 = result1 + shift0;
      result1 = r1 % MULTIPLER_LONGWORD_DECIMAL;
      final long r2 = result2 + shift1 + r1 / MULTIPLER_LONGWORD_DECIMAL;
      result2 = r2 % MULTIPLER_LONGWORD_DECIMAL;
      final long r3 = shift2 + r2 / MULTIPLER_LONGWORD_DECIMAL;
      result3 = r3 % MULTIPLER_LONGWORD_DECIMAL;
      result4 = r3 / MULTIPLER_LONGWORD_DECIMAL;

    } else if (diffScale < TWO_X_LONGWORD_DECIMAL_DIGITS) {

      final long divideFactor = powerOfTenTable[TWO_X_LONGWORD_DECIMAL_DIGITS - diffScale];
      final long multiplyFactor = powerOfTenTable[diffScale - LONGWORD_DECIMAL_DIGITS];

      final long r1 = result1 + (shift0 % divideFactor) * multiplyFactor;
      result1 = r1 % MULTIPLER_LONGWORD_DECIMAL;
      final long r2 =
          result2
              + shift0 / divideFactor
              + (shift1 % divideFactor) * multiplyFactor
              + r1 / MULTIPLER_LONGWORD_DECIMAL;
      result2 = r2 % MULTIPLER_LONGWORD_DECIMAL;
      final long r3 =
          shift1 / divideFactor
              + (shift2 % divideFactor) * multiplyFactor
              + r2 / MULTIPLER_LONGWORD_DECIMAL;
      result3 = r3 % MULTIPLER_LONGWORD_DECIMAL;
      final long r4 = shift2 / divideFactor + r3 / MULTIPLER_LONGWORD_DECIMAL;
      result4 = r4 % MULTIPLER_LONGWORD_DECIMAL;

    } else if (diffScale == TWO_X_LONGWORD_DECIMAL_DIGITS) {

      final long r2 = result2 + shift0;
      result2 = r2 % MULTIPLER_LONGWORD_DECIMAL;
      final long r3 = shift1 + r2 / MULTIPLER_LONGWORD_DECIMAL;
      result3 = r3 % MULTIPLER_LONGWORD_DECIMAL;
      final long r4 = shift2 + r3 / MULTIPLER_LONGWORD_DECIMAL;
      result4 = r4 % MULTIPLER_LONGWORD_DECIMAL;

    } else {

      final long divideFactor = powerOfTenTable[THREE_X_LONGWORD_DECIMAL_DIGITS - diffScale];
      final long multiplyFactor = powerOfTenTable[diffScale - TWO_X_LONGWORD_DECIMAL_DIGITS];

      final long r2 = result2 + (shift0 % divideFactor) * multiplyFactor;
      result2 = r2 % MULTIPLER_LONGWORD_DECIMAL;
      final long r3 =
          shift0 / divideFactor
              + (shift1 % divideFactor) * multiplyFactor
              + r2 / MULTIPLER_LONGWORD_DECIMAL;
      result3 = r3 % MULTIPLER_LONGWORD_DECIMAL;
      final long r4 =
          shift1 / divideFactor
              + (shift2 % divideFactor) * multiplyFactor
              + r3 / MULTIPLER_LONGWORD_DECIMAL;
      result4 = r4 % MULTIPLER_LONGWORD_DECIMAL;
      if (shift2 / divideFactor != 0) {
        throw new RuntimeException("Unexpected overflow");
      }
    }

    return doFinishAddSubtractDifferentScale(
        result0, result1, result2, result3, result4, resultScale, fastResult);
  }