in kyuubi-hive-jdbc/src/main/java/org/apache/kyuubi/jdbc/hive/common/FastHiveDecimalImpl.java [1415:1540]
public static boolean doBinaryToDecimalConversion(
long lowerWord,
long middleWord,
long highWord,
FastHiveDecimal middleWordMultiplier,
FastHiveDecimal highWordMultiplier,
FastHiveDecimal fastResult) {
/*
* Challenge: How to do the math to get this raw binary back to our decimal form.
*
* Briefly, for the middle and upper binary words, convert the middle/upper word into a decimal
* long words and then multiply those by the binary word's power of 2.
*
* And, add the multiply results into the result decimal longwords.
*
*/
long result0 = lowerWord % MULTIPLER_LONGWORD_DECIMAL;
long result1 = lowerWord / MULTIPLER_LONGWORD_DECIMAL;
long result2 = 0;
if (middleWord != 0 || highWord != 0) {
if (highWord == 0) {
// Form result from lower and middle words.
if (!fastMultiply5x5HalfWords(
middleWord % MULTIPLER_LONGWORD_DECIMAL,
middleWord / MULTIPLER_LONGWORD_DECIMAL,
0,
middleWordMultiplier.fast0,
middleWordMultiplier.fast1,
middleWordMultiplier.fast2,
fastResult)) {
return false;
}
final long calc0 = result0 + fastResult.fast0;
result0 = calc0 % MULTIPLER_LONGWORD_DECIMAL;
final long calc1 = calc0 / MULTIPLER_LONGWORD_DECIMAL + result1 + fastResult.fast1;
result1 = calc1 % MULTIPLER_LONGWORD_DECIMAL;
result2 = calc1 / MULTIPLER_LONGWORD_DECIMAL + fastResult.fast2;
} else if (middleWord == 0) {
// Form result from lower and high words.
if (!fastMultiply5x5HalfWords(
highWord % MULTIPLER_LONGWORD_DECIMAL,
highWord / MULTIPLER_LONGWORD_DECIMAL,
0,
highWordMultiplier.fast0,
highWordMultiplier.fast1,
highWordMultiplier.fast2,
fastResult)) {
return false;
}
final long calc0 = result0 + fastResult.fast0;
result0 = calc0 % MULTIPLER_LONGWORD_DECIMAL;
final long calc1 = calc0 / MULTIPLER_LONGWORD_DECIMAL + result1 + fastResult.fast1;
result1 = calc1 % MULTIPLER_LONGWORD_DECIMAL;
result2 = calc1 / MULTIPLER_LONGWORD_DECIMAL + fastResult.fast2;
} else {
// Form result from lower, middle, and middle words.
if (!fastMultiply5x5HalfWords(
middleWord % MULTIPLER_LONGWORD_DECIMAL,
middleWord / MULTIPLER_LONGWORD_DECIMAL,
0,
middleWordMultiplier.fast0,
middleWordMultiplier.fast1,
middleWordMultiplier.fast2,
fastResult)) {
return false;
}
long middleResult0 = fastResult.fast0;
long middleResult1 = fastResult.fast1;
long middleResult2 = fastResult.fast2;
if (!fastMultiply5x5HalfWords(
highWord % MULTIPLER_LONGWORD_DECIMAL,
highWord / MULTIPLER_LONGWORD_DECIMAL,
0,
highWordMultiplier.fast0,
highWordMultiplier.fast1,
highWordMultiplier.fast2,
fastResult)) {
return false;
}
long calc0 = result0 + middleResult0 + fastResult.fast0;
result0 = calc0 % MULTIPLER_LONGWORD_DECIMAL;
long calc1 =
calc0 / MULTIPLER_LONGWORD_DECIMAL + result1 + middleResult1 + fastResult.fast1;
result1 = calc1 % MULTIPLER_LONGWORD_DECIMAL;
result2 = calc1 / MULTIPLER_LONGWORD_DECIMAL + middleResult2 + fastResult.fast2;
}
}
// Let caller set negative sign if necessary.
if (result2 != 0) {
fastResult.fastIntegerDigitCount =
TWO_X_LONGWORD_DECIMAL_DIGITS + fastHighWordPrecision(result2);
fastResult.fastSignum = 1;
} else if (result1 != 0) {
fastResult.fastIntegerDigitCount = LONGWORD_DECIMAL_DIGITS + fastHighWordPrecision(result1);
fastResult.fastSignum = 1;
} else if (result0 != 0) {
fastResult.fastIntegerDigitCount = fastHighWordPrecision(result0);
fastResult.fastSignum = 1;
} else {
fastResult.fastIntegerDigitCount = 0;
fastResult.fastSignum = 0;
}
fastResult.fast0 = result0;
fastResult.fast1 = result1;
fastResult.fast2 = result2;
return true;
}