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