in storage-api/src/java/org/apache/hadoop/hive/common/type/FastHiveDecimalImpl.java [6903:7504]
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);
}