private static boolean fastSubtractDifferentScale()

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


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

    int diffScale;
    int resultScale;

    long result0 = 0;
    long result1 = 0;
    long result2 = 0;
    long result3 = 0;
    long result4 = 0;

    // Since subtraction is not commutative, we can must subtract in the order passed in.
    if (leftScale > rightScale) {

      // Since left has a longer digit tail and it doesn't move; we will shift the right digits
      // as we do our addition into the result.

      diffScale = leftScale - rightScale;
      resultScale = leftScale;

      if (diffScale < LONGWORD_DECIMAL_DIGITS) {

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

        final long r0 = leftFast0 - (rightFast0 % divideFactor) * multiplyFactor;
        long r1;
        if (r0 < 0) {
          result0 = r0 + MULTIPLER_LONGWORD_DECIMAL;
          r1 =
              leftFast1
                  - rightFast0 / divideFactor
                  - (rightFast1 % divideFactor) * multiplyFactor
                  - 1;
        } else {
          result0 = r0;
          r1 = leftFast1 - rightFast0 / divideFactor - (rightFast1 % divideFactor) * multiplyFactor;
        }
        long r2;
        if (r1 < 0) {
          result1 = r1 + MULTIPLER_LONGWORD_DECIMAL;
          r2 =
              leftFast2
                  - rightFast1 / divideFactor
                  - (rightFast2 % divideFactor) * multiplyFactor
                  - 1;
        } else {
          result1 = r1;
          r2 = leftFast2 - rightFast1 / divideFactor - (rightFast2 % divideFactor) * multiplyFactor;
        }
        long r3;
        if (r2 < 0) {
          result2 = r2 + MULTIPLER_LONGWORD_DECIMAL;
          r3 = -(rightFast2 / divideFactor) - 1;
        } else {
          result2 = r2;
          r3 = -(rightFast2 / divideFactor);
        }
        long r4;
        if (r3 < 0) {
          result3 = r3 + MULTIPLER_LONGWORD_DECIMAL;
          r4 = -1;
        } else {
          result3 = r3;
          r4 = 0;
        }
        if (r4 != 0) {
          throw new RuntimeException("Unexpected underflow");
        }

      } else if (diffScale == LONGWORD_DECIMAL_DIGITS) {

        result0 = leftFast0;
        final long r1 = leftFast1 - rightFast0;
        long r2;
        if (r1 < 0) {
          result1 = r1 + MULTIPLER_LONGWORD_DECIMAL;
          r2 = leftFast2 - rightFast1 - 1;
        } else {
          result1 = r1;
          r2 = leftFast2 - rightFast1;
        }
        long r3;
        if (r2 < 0) {
          result2 = r2 + MULTIPLER_LONGWORD_DECIMAL;
          r3 = -rightFast2 - 1;
        } else {
          result2 = r2;
          r3 = -rightFast2;
        }
        if (r3 != 0) {
          throw new RuntimeException("Unexpected underflow");
        }

      } 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];

        result0 = leftFast0;
        final long r1 = leftFast1 - (rightFast0 % divideFactor) * multiplyFactor;
        long r2;
        if (r1 < 0) {
          result1 = r1 + MULTIPLER_LONGWORD_DECIMAL;
          r2 =
              leftFast2
                  - rightFast0 / divideFactor
                  - (rightFast1 % divideFactor) * multiplyFactor
                  - 1;
        } else {
          result1 = r1;
          r2 = leftFast2 - rightFast0 / divideFactor - (rightFast1 % divideFactor) * multiplyFactor;
        }
        long r3;
        if (r2 < 0) {
          result2 = r2 + MULTIPLER_LONGWORD_DECIMAL;
          r3 = -rightFast1 / divideFactor - (rightFast2 % divideFactor) * multiplyFactor - 1;
        } else {
          result2 = r2;
          r3 = -rightFast1 / divideFactor - (rightFast2 % divideFactor) * multiplyFactor;
        }
        long r4;
        if (r3 < 0) {
          result3 = r3 + MULTIPLER_LONGWORD_DECIMAL;
          r4 = -rightFast2 / divideFactor - 1;
        } else {
          result3 = r3;
          r4 = -rightFast2 / divideFactor;
        }
        long r5;
        if (r4 < 0) {
          result4 = r4 + MULTIPLER_LONGWORD_DECIMAL;
          r5 = -1;
        } else {
          result4 = r4;
          r5 = 0;
        }
        if (r5 != 0) {
          throw new RuntimeException("Unexpected underflow");
        }

      } else if (diffScale == TWO_X_LONGWORD_DECIMAL_DIGITS) {

        result0 = leftFast0;
        result1 = leftFast1;
        final long r2 = leftFast2 - rightFast0;
        long r3;
        if (r2 < 0) {
          result2 = r2 + MULTIPLER_LONGWORD_DECIMAL;
          r3 = -rightFast1 - 1;
        } else {
          result2 = r2;
          r3 = -rightFast1;
        }
        long r4;
        if (r3 < 0) {
          result3 = r3 + MULTIPLER_LONGWORD_DECIMAL;
          r4 = -rightFast2 - 1;
        } else {
          result3 = r3;
          r4 = -rightFast2;
        }
        long r5;
        if (r4 < 0) {
          result4 = r4 + MULTIPLER_LONGWORD_DECIMAL;
          r5 = -1;
        } else {
          result4 = r4;
          r5 = 0;
        }
        if (r5 != 0) {
          throw new RuntimeException("Unexpected underflow");
        }

      } else {

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

        result0 = leftFast0;
        result1 = leftFast1;
        final long r2 = leftFast2 - (rightFast0 % divideFactor) * multiplyFactor;
        long r3;
        if (r2 < 0) {
          result2 = r2 + MULTIPLER_LONGWORD_DECIMAL;
          r3 = -(rightFast0 / divideFactor) - (rightFast1 % divideFactor) * multiplyFactor - 1;
        } else {
          result2 = r2;
          r3 = -(rightFast0 / divideFactor) - (rightFast1 % divideFactor) * multiplyFactor;
        }
        long r4;
        if (r3 < 0) {
          result3 = r3 + MULTIPLER_LONGWORD_DECIMAL;
          r4 = -(rightFast1 / divideFactor) - (rightFast2 % divideFactor) * multiplyFactor - 1;
        } else {
          result3 = r3;
          r4 = -(rightFast1 / divideFactor) - (rightFast2 % divideFactor) * multiplyFactor;
        }
        long r5;
        if (r4 < 0) {
          result4 = r4 + MULTIPLER_LONGWORD_DECIMAL;
          r5 = -(rightFast2 / divideFactor) - 1;
        } else {
          result4 = r4;
          r5 = -(rightFast2 / divideFactor);
        }
        if (r5 != 0) {
          throw new RuntimeException("Unexpected underflow");
        }
      }
    } else {

      // Since right has a longer digit tail and it doesn't move; we will shift the left digits
      // as we do our addition into the result.

      diffScale = rightScale - leftScale;
      resultScale = rightScale;

      if (diffScale < LONGWORD_DECIMAL_DIGITS) {

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

        final long r0 = (leftFast0 % divideFactor) * multiplyFactor - rightFast0;
        long r1;
        if (r0 < 0) {
          result0 = r0 + MULTIPLER_LONGWORD_DECIMAL;
          r1 =
              leftFast0 / divideFactor
                  + (leftFast1 % divideFactor) * multiplyFactor
                  - rightFast1
                  - 1;
        } else {
          result0 = r0;
          r1 = leftFast0 / divideFactor + (leftFast1 % divideFactor) * multiplyFactor - rightFast1;
        }
        long r2;
        if (r1 < 0) {
          result1 = r1 + MULTIPLER_LONGWORD_DECIMAL;
          r2 =
              leftFast1 / divideFactor
                  + (leftFast2 % divideFactor) * multiplyFactor
                  - rightFast2
                  - 1;
        } else {
          result1 = r1;
          r2 = leftFast1 / divideFactor + (leftFast2 % divideFactor) * multiplyFactor - rightFast2;
        }
        long r3;
        if (r2 < 0) {
          result2 = r2 + MULTIPLER_LONGWORD_DECIMAL;
          r3 = leftFast2 / divideFactor - 1;
        } else {
          result2 = r2;
          r3 = leftFast2 / divideFactor;
        }
        long r4;
        if (r3 < 0) {
          result3 = r3 + MULTIPLER_LONGWORD_DECIMAL;
          r4 = -1;
        } else {
          result3 = r3;
          r4 = 0;
        }
        if (r4 != 0) {
          throw new RuntimeException("Unexpected underflow");
        }

      } else if (diffScale == LONGWORD_DECIMAL_DIGITS) {

        final long r0 = -rightFast0;
        long r1;
        if (r0 < 0) {
          result0 = r0 + MULTIPLER_LONGWORD_DECIMAL;
          r1 = leftFast0 - rightFast1 - 1;
        } else {
          result0 = r0;
          r1 = leftFast0 - rightFast1;
        }
        long r2;
        if (r1 < 0) {
          result1 = r1 + MULTIPLER_LONGWORD_DECIMAL;
          r2 = leftFast1 - rightFast2 - 1;
        } else {
          result1 = r1;
          r2 = leftFast1 - rightFast2;
        }
        long r3;
        if (r2 < 0) {
          result2 = r2 + MULTIPLER_LONGWORD_DECIMAL;
          r3 = leftFast2 - 1;
        } else {
          result2 = r2;
          r3 = leftFast2;
        }
        long r4;
        if (r3 < 0) {
          result3 = r3 + MULTIPLER_LONGWORD_DECIMAL;
          r4 = -1;
        } else {
          result3 = r3;
          r4 = 0;
        }
        if (r4 != 0) {
          throw new RuntimeException("Unexpected underflow");
        }

      } 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 r0 = -rightFast0;
        long r1;
        if (r0 < 0) {
          result0 = r0 + MULTIPLER_LONGWORD_DECIMAL;
          r1 = (leftFast0 % divideFactor) * multiplyFactor - rightFast1 - 1;
        } else {
          result0 = r0;
          r1 = (leftFast0 % divideFactor) * multiplyFactor - rightFast1;
        }
        long r2;
        if (r1 < 0) {
          result1 = r1 + MULTIPLER_LONGWORD_DECIMAL;
          r2 =
              leftFast0 / divideFactor
                  + (leftFast1 % divideFactor) * multiplyFactor
                  - rightFast2
                  - 1;
        } else {
          result1 = r1;
          r2 = leftFast0 / divideFactor + (leftFast1 % divideFactor) * multiplyFactor - rightFast2;
        }
        long r3;
        if (r2 < 0) {
          result2 = r2 + MULTIPLER_LONGWORD_DECIMAL;
          r3 = leftFast1 / divideFactor + (leftFast2 % divideFactor) * multiplyFactor - 1;
        } else {
          result2 = r2;
          r3 = leftFast1 / divideFactor + (leftFast2 % divideFactor) * multiplyFactor;
        }
        long r4;
        if (r3 < 0) {
          result3 = r3 + MULTIPLER_LONGWORD_DECIMAL;
          r4 = leftFast2 / divideFactor - 1;
        } else {
          result3 = r3;
          r4 = leftFast2 / divideFactor;
        }
        if (r4 < 0) {
          result4 = r4 + MULTIPLER_LONGWORD_DECIMAL;
        } else {
          result4 = r4;
        }

      } else if (diffScale == TWO_X_LONGWORD_DECIMAL_DIGITS) {

        final long r0 = -rightFast0;
        long r1;
        if (r0 < 0) {
          result0 = r0 + MULTIPLER_LONGWORD_DECIMAL;
          r1 = -rightFast1 - 1;
        } else {
          result0 = r0;
          r1 = -rightFast1;
        }
        long r2;
        if (r1 < 0) {
          result1 = r1 + MULTIPLER_LONGWORD_DECIMAL;
          r2 = leftFast0 - rightFast2 - 1;
        } else {
          result1 = r1;
          r2 = leftFast0 - rightFast2;
        }
        long r3;
        if (r2 < 0) {
          result2 = r2 + MULTIPLER_LONGWORD_DECIMAL;
          r3 = leftFast1 - 1;
        } else {
          result2 = r2;
          r3 = leftFast1;
        }
        long r4;
        if (r3 < 0) {
          result3 = r3 + MULTIPLER_LONGWORD_DECIMAL;
          r4 = leftFast2 - 1;
        } else {
          result3 = r3;
          r4 = leftFast2;
        }
        long r5;
        if (r4 < 0) {
          result4 = r4 + MULTIPLER_LONGWORD_DECIMAL;
          r5 = -1;
        } else {
          result4 = r4;
          r5 = 0;
        }
        if (r5 != 0) {
          throw new RuntimeException("Unexpected underflow");
        }

      } else {

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

        final long r0 = -rightFast0;
        long r1;
        if (r0 < 0) {
          result0 = r0 + MULTIPLER_LONGWORD_DECIMAL;
          r1 = -rightFast1 - 1;
        } else {
          result0 = r0;
          r1 = -rightFast1;
        }
        long r2;
        if (r1 < 0) {
          result1 = r1 + MULTIPLER_LONGWORD_DECIMAL;
          r2 = (leftFast0 % divideFactor) * multiplyFactor - rightFast2 - 1;
        } else {
          result1 = r1;
          r2 = (leftFast0 % divideFactor) * multiplyFactor - rightFast2;
        }
        long r3;
        if (r2 < 0) {
          result2 = r2 + MULTIPLER_LONGWORD_DECIMAL;
          r3 = leftFast0 / divideFactor + (leftFast1 % divideFactor) * multiplyFactor - 1;
        } else {
          result2 = r2;
          r3 = leftFast0 / divideFactor + (leftFast1 % divideFactor) * multiplyFactor;
        }
        long r4;
        if (r3 < 0) {
          result3 = r3 + MULTIPLER_LONGWORD_DECIMAL;
          r4 = leftFast1 / divideFactor + (leftFast2 % divideFactor) * multiplyFactor - 1;
        } else {
          result3 = r3;
          r4 = leftFast1 / divideFactor + (leftFast2 % divideFactor) * multiplyFactor;
        }
        long r5;
        if (r4 < 0) {
          result4 = r4 + MULTIPLER_LONGWORD_DECIMAL;
          r5 = leftFast2 / divideFactor - 1;
        } else {
          result4 = r4;
          r5 = leftFast2 / divideFactor;
        }
        if (r5 != 0) {
          throw new RuntimeException("Unexpected underflow");
        }
      }
    }

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