diff --git a/common/src/test/org/apache/hadoop/hive/common/type/TestDecimal128.java b/common/src/test/org/apache/hadoop/hive/common/type/TestDecimal128.java index 6824cd7..f188533 100644 --- a/common/src/test/org/apache/hadoop/hive/common/type/TestDecimal128.java +++ b/common/src/test/org/apache/hadoop/hive/common/type/TestDecimal128.java @@ -377,6 +377,12 @@ public void testKnownPriorErrors() { long a = 213474114411690L; long b = 5062120663L; verifyMultiplyDivideInverse(a, b); + + String a2 = "-605044214913338382"; // 18 digits + String b2 = "55269579109718297360"; // 20 digits + + // -33440539101030154945490585226577271520 is expected result + verifyHighPrecisionMultiplySingle(a2, b2); } // Test a set of random adds at high precision. @@ -418,6 +424,8 @@ private void verifyHighPrecisionAddSingle() { assertEquals(res1, res2); } + + // Test a set of random subtracts at high precision. @Test public void testHighPrecisionDecimal128Subtract() { @@ -490,7 +498,7 @@ private void verifyHighPrecisionMultiplySingle() { String res1 = r.toFormalString(); - // Now do the add with Java BigDecimal + // Now do the operation with Java BigDecimal BigDecimal bdA = new BigDecimal(sA); BigDecimal bdB = new BigDecimal(sB); BigDecimal bdR = bdA.multiply(bdB); @@ -498,9 +506,52 @@ private void verifyHighPrecisionMultiplySingle() { String res2 = bdR.toPlainString(); // Compare the results - assertEquals(res1, res2); + String message = "For operation " + a.toFormalString() + " * " + b.toFormalString(); + assertEquals(message, res1, res2); } + // Test a single, high-precision multiply of random inputs. + // Arguments must be integers with optional - sign, represented as strings. + // Arguments must have 1 to 37 digits and the number of total digits + // must be <= 38. + private void verifyHighPrecisionMultiplySingle(String argA, String argB) { + + Decimal128 a, b, r; + String sA, sB; + + // verify number of digits is <= 38 and each number has 1 or more digits + int aDigits = argA.length(); + aDigits -= argA.charAt(0) == '-' ? 1 : 0; + int bDigits = argB.length(); + bDigits -= argB.charAt(0) == '-' ? 1 : 0; + assertTrue(aDigits + bDigits <= 38 && aDigits > 0 && bDigits > 0); + + a = new Decimal128(); + sA = argA; + a.update(sA, (short) 0); + b = new Decimal128(); + sB = argB; + b.update(sB, (short) 0); + + r = new Decimal128(); + r.addDestructive(a, (short) 0); + r.multiplyDestructive(b, (short) 0); + + String res1 = r.toFormalString(); + + // Now do the operation with Java BigDecimal + BigDecimal bdA = new BigDecimal(sA); + BigDecimal bdB = new BigDecimal(sB); + BigDecimal bdR = bdA.multiply(bdB); + + String res2 = bdR.toPlainString(); + + // Compare the results + String message = "For operation " + a.toFormalString() + " * " + b.toFormalString(); + assertEquals(message, res2, res1); + } + + // Test a set of random divisions at high precision. @Test public void testHighPrecisionDecimal128Divide() {