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