private static boolean isRoundPortionHalfEven()

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


  private static boolean isRoundPortionHalfEven(
      long fast0, long fast1, long fast2, int roundingPoint) {

    boolean isRoundPortionHalfEven;
    if (roundingPoint < LONGWORD_DECIMAL_DIGITS) {

      // Lowest word gets integer rounding.

      // Divide down just before scaleDown to get round digit.
      final long roundDivisor = powerOfTenTable[roundingPoint - 1];
      final long withRoundDigit = fast0 / roundDivisor;
      final long roundDigit = withRoundDigit % 10;
      final long fast0Scaled = withRoundDigit / 10;

      if (roundDigit > 5) {
        isRoundPortionHalfEven = true;
      } else if (roundDigit == 5) {
        boolean exactlyOneHalf;
        if (roundingPoint - 1 == 0) {
          // Fraction below 0.5 is implicitly 0.
          exactlyOneHalf = true;
        } else {
          exactlyOneHalf = (fast0 % roundDivisor == 0);
        }

        // When fraction is exactly 0.5 and lowest new digit is odd, go towards even.
        if (exactlyOneHalf) {
          isRoundPortionHalfEven = (fast0Scaled % 2 == 1);
        } else {
          isRoundPortionHalfEven = true;
        }
      } else {
        isRoundPortionHalfEven = false;
      }

    } else if (roundingPoint < TWO_X_LONGWORD_DECIMAL_DIGITS) {

      // Middle word gets integer rounding.

      final int adjustedRoundingPoint = roundingPoint - LONGWORD_DECIMAL_DIGITS;

      long roundDigit;
      long fast1Scaled;
      if (adjustedRoundingPoint == 0) {
        // Grab round digit from lowest word.
        final long roundDivisor = MULTIPLER_LONGWORD_DECIMAL / 10;
        roundDigit = fast0 / roundDivisor;
        fast1Scaled = fast1;
        if (roundDigit > 5) {
          isRoundPortionHalfEven = true;
        } else if (roundDigit == 5) {
          boolean exactlyOneHalf = (fast0 % roundDivisor == 0);

          // When fraction is exactly 0.5 and lowest new digit is odd, go towards even.
          if (exactlyOneHalf) {
            isRoundPortionHalfEven = (fast1Scaled % 2 == 1);
          } else {
            isRoundPortionHalfEven = true;
          }
        } else {
          isRoundPortionHalfEven = false;
        }
      } else {
        // Divide down just before scaleDown to get round digit.
        final long roundDivisor = powerOfTenTable[adjustedRoundingPoint - 1];
        final long withRoundDigit = fast1 / roundDivisor;
        roundDigit = withRoundDigit % 10;
        fast1Scaled = withRoundDigit / 10;
        if (roundDigit > 5) {
          isRoundPortionHalfEven = true;
        } else if (roundDigit == 5) {
          boolean exactlyOneHalf;
          if (adjustedRoundingPoint - 1 == 0) {
            // Just examine the lower word.
            exactlyOneHalf = (fast0 == 0);
          } else {
            exactlyOneHalf = (fast0 == 0 && fast1 % roundDivisor == 0);
          }

          // When fraction is exactly 0.5 and lowest new digit is odd, go towards even.
          if (exactlyOneHalf) {
            isRoundPortionHalfEven = (fast1Scaled % 2 == 1);
          } else {
            isRoundPortionHalfEven = true;
          }
        } else {
          isRoundPortionHalfEven = false;
        }
      }

    } else {

      // High word gets integer rounding.

      final int adjustedRoundingPoint = roundingPoint - TWO_X_LONGWORD_DECIMAL_DIGITS;

      long roundDigit;
      long fast2Scaled;
      if (adjustedRoundingPoint == 0) {
        // Grab round digit from middle word.
        final long roundDivisor = MULTIPLER_LONGWORD_DECIMAL / 10;
        roundDigit = fast1 / roundDivisor;
        fast2Scaled = fast2;
        if (roundDigit > 5) {
          isRoundPortionHalfEven = true;
        } else if (roundDigit == 5) {
          boolean exactlyOneHalf = (fast1 % roundDivisor == 0 && fast0 == 0);

          // When fraction is exactly 0.5 and lowest new digit is odd, go towards even.
          if (exactlyOneHalf) {
            isRoundPortionHalfEven = (fast2Scaled % 2 == 1);
          } else {
            isRoundPortionHalfEven = true;
          }
        } else {
          isRoundPortionHalfEven = false;
        }
      } else {
        // Divide down just before scaleDown to get round digit.
        final long roundDivisor = powerOfTenTable[adjustedRoundingPoint - 1];
        final long withRoundDigit = fast2 / roundDivisor;
        roundDigit = withRoundDigit % 10;
        fast2Scaled = withRoundDigit / 10;
        if (roundDigit > 5) {
          isRoundPortionHalfEven = true;
        } else if (roundDigit == 5) {
          boolean exactlyOneHalf;
          if (adjustedRoundingPoint - 1 == 0) {
            // Just examine the middle and lower words.
            exactlyOneHalf = (fast1 == 0 && fast0 == 0);
          } else {
            exactlyOneHalf = (fast2 % roundDivisor == 0 && fast1 == 0 && fast0 == 0);
          }

          // When fraction is exactly 0.5 and lowest new digit is odd, go towards even.
          if (exactlyOneHalf) {
            isRoundPortionHalfEven = (fast2Scaled % 2 == 1);
          } else {
            isRoundPortionHalfEven = true;
          }
        } else {
          isRoundPortionHalfEven = false;
        }
      }
    }
    return isRoundPortionHalfEven;
  }