You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hive.apache.org by mm...@apache.org on 2016/12/22 08:32:31 UTC
[02/10] hive git commit: HIVE-15335: Fast Decimal (Matt McCline,
reviewed by Sergey Shelukhin, Prasanth Jayachandran, Owen O'Malley)
http://git-wip-us.apache.org/repos/asf/hive/blob/4ba713cc/storage-api/src/test/org/apache/hadoop/hive/common/type/TestHiveDecimal.java
----------------------------------------------------------------------
diff --git a/storage-api/src/test/org/apache/hadoop/hive/common/type/TestHiveDecimal.java b/storage-api/src/test/org/apache/hadoop/hive/common/type/TestHiveDecimal.java
new file mode 100644
index 0000000..f8a36e5
--- /dev/null
+++ b/storage-api/src/test/org/apache/hadoop/hive/common/type/TestHiveDecimal.java
@@ -0,0 +1,3404 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hive.common.type;
+
+import java.sql.Timestamp;
+import java.util.Random;
+import java.util.Arrays;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+import org.apache.hadoop.hive.serde2.io.HiveDecimalWritableV1;
+import org.apache.hadoop.hive.serde2.io.HiveDecimalWritable;
+import org.apache.hadoop.hive.common.type.RandomTypeUtil;
+import org.apache.hadoop.hive.ql.exec.vector.expressions.StringExpr;
+import org.apache.hadoop.hive.ql.util.TimestampUtils;
+
+import org.junit.*;
+
+import static org.junit.Assert.*;
+
+public class TestHiveDecimal extends HiveDecimalTestBase {
+
+ @Test
+ public void testInvalidStringInput() {
+
+ HiveDecimalV1 oldDec;
+ HiveDecimalV1 resultOldDec;
+ HiveDecimal dec;
+ HiveDecimal resultDec;
+
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create("-");
+ Assert.assertTrue(oldDec == null);
+ //---------------------------------------------------
+ dec = HiveDecimal.create("-");
+ Assert.assertTrue(dec == null);
+
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create("+");
+ Assert.assertTrue(oldDec == null);
+ //---------------------------------------------------
+ dec = HiveDecimal.create("+");
+ Assert.assertTrue(dec == null);
+
+ // Naked dot.
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create(".");
+ Assert.assertTrue(oldDec == null);
+ //---------------------------------------------------
+ dec = HiveDecimal.create(".");
+ Assert.assertTrue(dec == null);
+
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create("-.");
+ Assert.assertTrue(oldDec == null);
+ //---------------------------------------------------
+ dec = HiveDecimal.create("-.");
+ Assert.assertTrue(dec == null);
+
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create("+.");
+ Assert.assertTrue(oldDec == null);
+ //---------------------------------------------------
+ dec = HiveDecimal.create("+.");
+ Assert.assertTrue(dec == null);
+
+ // Naked E/e.
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create("E");
+ Assert.assertTrue(oldDec == null);
+ //---------------------------------------------------
+ dec = HiveDecimal.create("E");
+ Assert.assertTrue(dec == null);
+
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create(".E");
+ Assert.assertTrue(oldDec == null);
+ //---------------------------------------------------
+ dec = HiveDecimal.create(".E");
+ Assert.assertTrue(dec == null);
+
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create("-E");
+ Assert.assertTrue(oldDec == null);
+ //---------------------------------------------------
+ dec = HiveDecimal.create("-E");
+ Assert.assertTrue(dec == null);
+
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create("+E");
+ Assert.assertTrue(oldDec == null);
+ //---------------------------------------------------
+ dec = HiveDecimal.create("+E");
+ Assert.assertTrue(dec == null);
+
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create("e");
+ Assert.assertTrue(oldDec == null);
+ //---------------------------------------------------
+ dec = HiveDecimal.create("e");
+ Assert.assertTrue(dec == null);
+
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create(".e");
+ Assert.assertTrue(oldDec == null);
+ //---------------------------------------------------
+ dec = HiveDecimal.create(".e");
+ Assert.assertTrue(dec == null);
+
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create("-e");
+ Assert.assertTrue(oldDec == null);
+ //---------------------------------------------------
+ dec = HiveDecimal.create("-e");
+ Assert.assertTrue(dec == null);
+
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create("+e");
+ Assert.assertTrue(oldDec == null);
+ //---------------------------------------------------
+ dec = HiveDecimal.create("+e");
+ Assert.assertTrue(dec == null);
+
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create("error");
+ Assert.assertTrue(oldDec == null);
+ //---------------------------------------------------
+ dec = HiveDecimal.create("error");
+ Assert.assertTrue(dec == null);
+
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create("0x0");
+ Assert.assertTrue(oldDec == null);
+ //---------------------------------------------------
+ dec = HiveDecimal.create("0x0");
+ Assert.assertTrue(dec == null);
+
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create("0e");
+ Assert.assertTrue(oldDec == null);
+ //---------------------------------------------------
+ dec = HiveDecimal.create("0e");
+ Assert.assertTrue(dec == null);
+
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create("7e");
+ Assert.assertTrue(oldDec == null);
+ //---------------------------------------------------
+ dec = HiveDecimal.create("7e");
+ Assert.assertTrue(dec == null);
+
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create("233e-");
+ Assert.assertTrue(oldDec == null);
+ //---------------------------------------------------
+ dec = HiveDecimal.create("233e-");
+ Assert.assertTrue(dec == null);
+
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create("32e+");
+ Assert.assertTrue(oldDec == null);
+ //---------------------------------------------------
+ dec = HiveDecimal.create("32e+");
+ Assert.assertTrue(dec == null);
+
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create(".0e");
+ Assert.assertTrue(oldDec == null);
+ //---------------------------------------------------
+ dec = HiveDecimal.create(".0e");
+ Assert.assertTrue(dec == null);
+
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create(".4e");
+ Assert.assertTrue(oldDec == null);
+ //---------------------------------------------------
+ dec = HiveDecimal.create(".4e");
+ Assert.assertTrue(dec == null);
+ }
+
+ @Test
+ public void testVariousCases() {
+
+ HiveDecimalV1 oldDec;
+ HiveDecimalV1 resultOldDec;
+ HiveDecimal dec;
+ HiveDecimal resultDec;
+
+ BigDecimal bigDecimal = new BigDecimal("-99999999999999999999999999999999999999.99999999999999999");
+
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create(bigDecimal);
+ Assert.assertEquals("-100000000000000000000000000000000000000", oldDec.toString());
+ //---------------------------------------------------
+ dec = HiveDecimal.create(bigDecimal);
+ Assert.assertTrue(dec == null);
+
+ // One less integer digit...
+ bigDecimal = new BigDecimal("-9999999999999999999999999999999999999.99999999999999999");
+
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create(bigDecimal);
+ Assert.assertEquals("-10000000000000000000000000000000000000", oldDec.toString());
+ //---------------------------------------------------
+ dec = HiveDecimal.create(bigDecimal);
+ Assert.assertEquals("-10000000000000000000000000000000000000", dec.toString());
+
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create("101");
+ resultOldDec = HiveDecimalV1.enforcePrecisionScale(oldDec, 10, 0);
+ Assert.assertEquals("101", resultOldDec.toString());
+ //---------------------------------------------------
+ dec = HiveDecimal.create("101");
+ resultDec = HiveDecimal.enforcePrecisionScale(dec, 10, 0);
+ Assert.assertEquals("101", resultDec.toString());
+
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create("1");
+ resultOldDec = oldDec.scaleByPowerOfTen(-99);
+ Assert.assertEquals("0", resultOldDec.toString());
+ //---------------------------------------------------
+ dec = HiveDecimal.create("1");
+ resultDec = dec.scaleByPowerOfTen(-99);
+ Assert.assertEquals("0", resultDec.toString());
+ }
+
+ @Test
+ public void testCreateFromBigIntegerRounding() {
+
+ BigInteger bigInt;
+ HiveDecimalV1 oldDec;
+ HiveDecimal dec;
+
+ // 1786135888657847525803324040144343378.09799306448796128931113691624
+ bigInt = new BigInteger(
+ "178613588865784752580332404014434337809799306448796128931113691624");
+ Assert.assertEquals("178613588865784752580332404014434337809799306448796128931113691624", bigInt.toString());
+ // 12345678901234567890123456789012345678
+ // 1 2 3
+ // 12345678901234567890123456789
+ dec = HiveDecimal.create(bigInt, 29);
+ Assert.assertEquals("1786135888657847525803324040144343378.1", dec.toString());
+
+ // 8.090000000000000000000000000000000000000123456
+ bigInt = new BigInteger(
+ "8090000000000000000000000000000000000000123456");
+ // 123456789012345678901234567890123456789012345
+ // 1 2 3 4
+ Assert.assertEquals("8090000000000000000000000000000000000000123456", bigInt.toString());
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create(bigInt, 45);
+ Assert.assertEquals("8.09", oldDec.toString());
+ //---------------------------------------------------
+ dec = HiveDecimal.create(bigInt, 45);
+ Assert.assertEquals("8.09", dec.toString());
+
+ // 99999999.99999999999999999999999999999949999
+ // MAX_DECIMAL 9's WITH NO ROUND (longer than 38 digits)
+ bigInt = new BigInteger(
+ "9999999999999999999999999999999999999949999");
+ // 12345678901234567890123456789012345678
+ // 1 2 3
+ // 99999999.99999999999999999999999999999949999
+ Assert.assertEquals("9999999999999999999999999999999999999949999", bigInt.toString());
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create(bigInt, 35);
+ Assert.assertEquals("99999999.999999999999999999999999999999", oldDec.toString());
+ //---------------------------------------------------
+ // Without the round, this conversion fails.
+ dec = HiveDecimal.create(bigInt, 35);
+ Assert.assertEquals("99999999.999999999999999999999999999999", dec.toString());
+
+ // MAX_DECIMAL 9's WITH ROUND.
+ bigInt = new BigInteger(
+ "9999999999999999999999999999999999999979999");
+ // 12346678.901234667890123466789012346678
+ // 1 2 3
+ Assert.assertEquals("9999999999999999999999999999999999999979999", bigInt.toString());
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create(bigInt, 35);
+ Assert.assertEquals("100000000", oldDec.toString());
+ //---------------------------------------------------
+ dec = HiveDecimal.create(bigInt, 35);
+ Assert.assertEquals("100000000", dec.toString());
+ }
+
+ @Test
+ public void testCreateFromBigDecimal() {
+
+ BigDecimal bigDec;
+ HiveDecimalV1 oldDec;
+ HiveDecimal dec;
+
+ bigDec = new BigDecimal("0");
+ Assert.assertEquals("0", bigDec.toString());
+ dec = HiveDecimal.create(bigDec);
+ Assert.assertEquals("0", dec.toString());
+
+ bigDec = new BigDecimal("1");
+ Assert.assertEquals("1", bigDec.toString());
+ dec = HiveDecimal.create(bigDec);
+ Assert.assertEquals("1", dec.toString());
+
+ bigDec = new BigDecimal("0.999");
+ Assert.assertEquals("0.999", bigDec.toString());
+ dec = HiveDecimal.create(bigDec);
+ Assert.assertEquals("0.999", dec.toString());
+
+ // HiveDecimal suppresses trailing zeroes.
+ bigDec = new BigDecimal("0.9990");
+ Assert.assertEquals("0.9990", bigDec.toString());
+ dec = HiveDecimal.create(bigDec);
+ Assert.assertEquals("0.999", dec.toString());
+ }
+
+ @Test
+ public void testCreateFromBigDecimalRounding() {
+
+ BigDecimal bigDec;
+ HiveDecimalV1 oldDec;
+ HiveDecimal dec;
+
+ bigDec = new BigDecimal(
+ "1786135888657847525803324040144343378.09799306448796128931113691624");
+ Assert.assertEquals("1786135888657847525803324040144343378.09799306448796128931113691624", bigDec.toString());
+ // 1234567890123456789012345678901234567.8
+ // 1 2 3
+ // Without the round, this conversion fails.
+ dec = HiveDecimal.create(bigDec, false);
+ Assert.assertTrue(dec == null);
+ dec = HiveDecimal.create(bigDec, true);
+ Assert.assertEquals("1786135888657847525803324040144343378.1", dec.toString());
+
+ bigDec = new BigDecimal(
+ "8.090000000000000000000000000000000000000123456");
+ // 1.23456789012345678901234567890123456789012345
+ // 1 2 3 4
+ Assert.assertEquals("8.090000000000000000000000000000000000000123456", bigDec.toString());
+ //---------------------------------------------------
+ HiveDecimalV1 oldDec4 = HiveDecimalV1.create(bigDec, false);
+ Assert.assertTrue(oldDec4 == null);
+ oldDec4 = HiveDecimalV1.create(bigDec, true);
+ Assert.assertEquals("8.09", oldDec4.toString());
+ //---------------------------------------------------
+ // Without the round, this conversion fails.
+ dec = HiveDecimal.create(bigDec, false);
+ Assert.assertTrue(dec == null);
+ dec = HiveDecimal.create(bigDec, true);
+ Assert.assertEquals("8.09", dec.toString());
+
+ // MAX_DECIMAL 9's WITH NO ROUND (longer than 38 digits)
+ bigDec = new BigDecimal(
+ "99999999.99999999999999999999999999999949999");
+ // 12345678.901234567890123456789012345678
+ // 1 2 3
+ Assert.assertEquals("99999999.99999999999999999999999999999949999", bigDec.toString());
+ //---------------------------------------------------
+ HiveDecimalV1 oldDec5 = HiveDecimalV1.create(bigDec, false);
+ Assert.assertTrue(oldDec5 == null);
+ oldDec5 = HiveDecimalV1.create(bigDec, true);
+ Assert.assertEquals("99999999.999999999999999999999999999999", oldDec5.toString());
+ //---------------------------------------------------
+ dec = HiveDecimal.create(bigDec, false);
+ Assert.assertTrue(dec == null);
+ dec = HiveDecimal.create(bigDec, true);
+ Assert.assertEquals("99999999.999999999999999999999999999999", dec.toString());
+
+ // MAX_DECIMAL 9's WITH ROUND.
+ bigDec = new BigDecimal(
+ "99999999.99999999999999999999999999999979999");
+ // 12346678.901234667890123466789012346678
+ // 1 2 3
+ Assert.assertEquals("99999999.99999999999999999999999999999979999", bigDec.toString());
+ //---------------------------------------------------
+ HiveDecimalV1 oldDec6 = HiveDecimalV1.create(bigDec, false);
+ Assert.assertTrue(oldDec6 == null);
+ oldDec6 = HiveDecimalV1.create(bigDec, true);
+ Assert.assertEquals("100000000", oldDec6.toString());
+ //---------------------------------------------------
+ dec = HiveDecimal.create(bigDec, false);
+ Assert.assertTrue(dec == null);
+ dec = HiveDecimal.create(bigDec, true);
+ Assert.assertEquals("100000000", dec.toString());
+ }
+
+
+ @Test
+ public void testPrecisionScaleEnforcement() {
+
+ HiveDecimalV1 oldDec;
+ HiveDecimalV1 oldResultDec;
+
+ HiveDecimal dec;
+ HiveDecimal resultDec;
+
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create("0.02538461538461538461538461538461538462");
+ Assert.assertEquals("0.02538461538461538461538",
+ HiveDecimalV1.enforcePrecisionScale(oldDec, 38, 23).toString());
+ //---------------------------------------------------
+ dec = HiveDecimal.create("0.02538461538461538461538461538461538462");
+ Assert.assertEquals("0.02538461538461538461538",
+ HiveDecimal.enforcePrecisionScale(dec, 38, 23).toString());
+
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create("005.34000");
+ Assert.assertEquals(oldDec.precision(), 3); // 1 integer digit; 2 fraction digits.
+ Assert.assertEquals(oldDec.scale(), 2); // Trailing zeroes are suppressed.
+ //---------------------------------------------------
+ dec = HiveDecimal.create("005.34000");
+ Assert.assertEquals(dec.precision(), 3); // 1 integer digit; 2 fraction digits.
+ Assert.assertEquals(dec.scale(), 2); // Trailing zeroes are suppressed.
+
+ dec = HiveDecimal.create("178613588865784752580332404014434337809799306448796128931113691624");
+ Assert.assertNull(dec);
+
+ // Rounding numbers that increase int digits
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create("9.5");
+ Assert.assertEquals("10",
+ HiveDecimalV1.enforcePrecisionScale(oldDec, 2, 0).toString());
+ Assert.assertNull(
+ HiveDecimalV1.enforcePrecisionScale(oldDec, 1, 0));
+ oldDec = HiveDecimalV1.create("9.4");
+ Assert.assertEquals("9",
+ HiveDecimalV1.enforcePrecisionScale(oldDec, 1, 0).toString());
+ //---------------------------------------------------
+ dec = HiveDecimal.create("9.5");
+ Assert.assertEquals("10",
+ HiveDecimal.enforcePrecisionScale(dec, 2, 0).toString());
+ Assert.assertNull(
+ HiveDecimal.enforcePrecisionScale(dec, 1, 0));
+ dec = HiveDecimal.create("9.4");
+ Assert.assertEquals("9",
+ HiveDecimal.enforcePrecisionScale(dec, 1, 0).toString());
+ }
+
+ @Test
+ public void testPrecisionScaleEnforcementEdgeCond() {
+
+ // Since HiveDecimal now uses FastHiveDecimal which stores 16 decimal digits per long,
+ // lets test edge conditions here.
+
+ HiveDecimal fifteenFractionalNinesDec = HiveDecimal.create("0.999999999999999");
+ Assert.assertNotNull(fifteenFractionalNinesDec);
+ Assert.assertEquals("0.999999999999999",
+ HiveDecimal.enforcePrecisionScale(fifteenFractionalNinesDec, 15, 15).toString());
+
+ HiveDecimal sixteenFractionalNines = HiveDecimal.create("0.9999999999999999");
+ Assert.assertNotNull(sixteenFractionalNines);
+ Assert.assertEquals("0.9999999999999999",
+ HiveDecimal.enforcePrecisionScale(sixteenFractionalNines, 16, 16).toString());
+
+ HiveDecimal seventeenFractionalNines = HiveDecimal.create("0.99999999999999999");
+ Assert.assertNotNull(seventeenFractionalNines);
+ Assert.assertEquals("0.99999999999999999",
+ HiveDecimal.enforcePrecisionScale(seventeenFractionalNines, 17, 17).toString());
+
+ }
+
+ @Test
+ public void testTrailingZeroRemovalAfterEnforcement() {
+ String decStr = "8.090000000000000000000000000000000000000123456";
+ // 123456789012345678901234567890123456789012345
+ // 1 2 3 4
+ HiveDecimal dec = HiveDecimal.create(decStr);
+ Assert.assertEquals("8.09", dec.toString());
+ }
+
+ @Test
+ public void testMultiply() {
+
+ // This multiply produces more than 38 digits --> overflow.
+ //---------------------------------------------------
+ HiveDecimalV1 oldDec1 = HiveDecimalV1.create("0.00001786135888657847525803");
+ HiveDecimalV1 oldDec2 = HiveDecimalV1.create("3.0000123456789");
+ HiveDecimalV1 oldResult = oldDec1.multiply(oldDec2);
+ Assert.assertTrue(oldResult == null);
+ //---------------------------------------------------
+ HiveDecimal dec1 = HiveDecimal.create("0.00001786135888657847525803");
+ HiveDecimal dec2 = HiveDecimal.create("3.0000123456789");
+ HiveDecimal result = dec1.multiply(dec2);
+ Assert.assertTrue(result == null);
+
+ dec1 = HiveDecimal.create("178613588865784752580323232232323444.4");
+ dec2 = HiveDecimal.create("178613588865784752580302323232.3");
+ Assert.assertNull(dec1.multiply(dec2)); // i.e. Overflow.
+
+ dec1 = HiveDecimal.create("47.324");
+ dec2 = HiveDecimal.create("9232.309");
+ Assert.assertEquals("436909.791116", dec1.multiply(dec2).toString());
+
+ dec1 = HiveDecimal.create("3.140");
+ dec2 = HiveDecimal.create("1.00");
+ Assert.assertEquals("3.14", dec1.multiply(dec2).toString());
+
+ dec1 = HiveDecimal.create("43.010");
+ dec2 = HiveDecimal.create("2");
+ Assert.assertEquals("86.02", dec1.multiply(dec2).toString());
+ }
+
+ @Test
+ public void testMultiply2() {
+ // 0.09765625BD * 0.09765625BD * 0.0125BD * 578992BD
+ HiveDecimal dec1 = HiveDecimal.create("0.09765625");
+ HiveDecimal dec2 = HiveDecimal.create("0.09765625");
+ HiveDecimal dec3 = HiveDecimal.create("0.0125");
+ HiveDecimal dec4 = HiveDecimal.create("578992");
+ HiveDecimal result1 = dec1.multiply(dec2);
+ Assert.assertNotNull(result1);
+ HiveDecimal result2 = result1.multiply(dec3);
+ Assert.assertNotNull(result2);
+ HiveDecimal result = result2.multiply(dec4);
+ Assert.assertNotNull(result);
+ Assert.assertEquals("69.0212249755859375", result.toString());
+ }
+
+ @Test
+ public void testPow() {
+
+ HiveDecimal dec;
+
+ dec = HiveDecimal.create("3.00001415926");
+ HiveDecimal decPow2 = dec.pow(2);
+ HiveDecimal decMultiplyTwice = dec.multiply(dec);
+ Assert.assertEquals(decPow2, decMultiplyTwice);
+
+ dec = HiveDecimal.create("0.000017861358882");
+ dec = dec.pow(3);
+ Assert.assertNull(dec);
+
+ dec = HiveDecimal.create("3.140");
+ Assert.assertEquals("9.8596", dec.pow(2).toString());
+ }
+
+ @Test
+ public void testScaleByPowerOfTen() {
+
+ HiveDecimalV1 oldDec;
+ HiveDecimal dec;
+ HiveDecimalV1 oldResultDec;
+ HiveDecimal resultDec;
+
+ //**********************************************************************************************
+
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create(
+ "1");
+ Assert.assertEquals(0, oldDec.scale());
+ oldResultDec = oldDec.scaleByPowerOfTen(2);
+ Assert.assertEquals(
+ "100", oldResultDec.toString());
+ //---------------------------------------------------
+ dec = HiveDecimal.create(
+ "1");
+ Assert.assertEquals(0, dec.scale());
+ // resultDec = dec.scaleByPowerOfTen(2);
+ // Assert.assertEquals(
+ // "100", resultDec.toString());
+
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create(
+ "0.00000000000000000000000000000000000001");
+ Assert.assertEquals(38, oldDec.scale());
+ oldResultDec = oldDec.scaleByPowerOfTen(2);
+ Assert.assertEquals(
+ "0.000000000000000000000000000000000001", oldResultDec.toString());
+ //---------------------------------------------------
+ dec = HiveDecimal.create(
+ "0.00000000000000000000000000000000000001");
+ Assert.assertEquals(38, dec.scale());
+ resultDec = dec.scaleByPowerOfTen(2);
+ Assert.assertEquals(
+ "0.000000000000000000000000000000000001", resultDec.toString());
+
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create(
+ "0.00000000000000000000000000000000000001");
+ Assert.assertEquals(38, oldDec.scale());
+ oldResultDec = oldDec.scaleByPowerOfTen(38);
+ Assert.assertEquals(
+ "1", oldResultDec.toString());
+ //---------------------------------------------------
+ dec = HiveDecimal.create(
+ "0.00000000000000000000000000000000000001");
+ Assert.assertEquals(38, dec.scale());
+ resultDec = dec.scaleByPowerOfTen(38);
+ Assert.assertEquals(
+ "1", resultDec.toString());
+
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create(
+ "0.00000000000000000000000000000000000001");
+ Assert.assertEquals(38, oldDec.scale());
+ oldResultDec = oldDec.scaleByPowerOfTen(2 * 38 - 1);
+ Assert.assertEquals(
+ "10000000000000000000000000000000000000", oldResultDec.toString());
+ Assert.assertEquals(0, oldResultDec.scale());
+ //---------------------------------------------------
+ dec = HiveDecimal.create(
+ "0.00000000000000000000000000000000000001");
+ Assert.assertEquals(38, dec.scale());
+ resultDec = dec.scaleByPowerOfTen(2 * 38 - 1);
+ Assert.assertEquals(
+ "10000000000000000000000000000000000000", resultDec.toString());
+ Assert.assertEquals(0, resultDec.scale());
+
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create(
+ "0.00000000000000000000000000000000000001");
+ Assert.assertEquals(38, oldDec.scale());
+ oldResultDec = oldDec.scaleByPowerOfTen(2 * 38);
+ Assert.assertTrue(oldResultDec == null);
+ //---------------------------------------------------
+ dec = HiveDecimal.create(
+ "0.00000000000000000000000000000000000001");
+ Assert.assertEquals(38, dec.scale());
+ resultDec = dec.scaleByPowerOfTen(2 * 38);
+ Assert.assertTrue(resultDec == null);
+
+
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create(
+ "0.00000000000000000000000000000000000022");
+ Assert.assertEquals(38, oldDec.scale());
+ oldResultDec = oldDec.scaleByPowerOfTen(38);
+ Assert.assertEquals(
+ "22", oldResultDec.toString());
+ Assert.assertEquals(0, oldResultDec.scale());
+ //---------------------------------------------------
+ dec = HiveDecimal.create(
+ "0.00000000000000000000000000000000000022");
+ Assert.assertEquals(38, dec.scale());
+ resultDec = dec.scaleByPowerOfTen(38);
+ Assert.assertEquals(
+ "22", resultDec.toString());
+ Assert.assertEquals(0, resultDec.scale());
+
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create("3.00001415926");
+ Assert.assertEquals(11, oldDec.scale());
+ oldResultDec = oldDec.scaleByPowerOfTen(2);
+ Assert.assertEquals("300.001415926", oldResultDec.toString());
+ Assert.assertEquals(9, oldResultDec.scale());
+ oldResultDec = oldDec.scaleByPowerOfTen(5);
+ Assert.assertEquals("300001.415926", oldResultDec.toString());
+ Assert.assertEquals(6, oldResultDec.scale());
+ oldResultDec = oldDec.scaleByPowerOfTen(18);
+ Assert.assertEquals("3000014159260000000", oldResultDec.toString());
+ Assert.assertEquals(0, oldResultDec.scale());
+ oldResultDec = oldDec.scaleByPowerOfTen(35);
+ Assert.assertEquals("300001415926000000000000000000000000", oldResultDec.toString());
+ Assert.assertEquals(0, oldResultDec.scale());
+ oldResultDec = oldDec.scaleByPowerOfTen(37);
+ Assert.assertEquals("30000141592600000000000000000000000000", oldResultDec.toString());
+ Assert.assertEquals(0, oldResultDec.scale());
+ //---------------------------------------------------
+ dec = HiveDecimal.create("3.00001415926");
+ Assert.assertEquals(11, dec.scale());
+ Assert.assertEquals(1, dec.integerDigitCount());
+ resultDec = dec.scaleByPowerOfTen(2);
+ Assert.assertEquals("300.001415926", resultDec.toString());
+ Assert.assertEquals(9, resultDec.scale());
+ Assert.assertEquals(3, resultDec.integerDigitCount());
+ resultDec = dec.scaleByPowerOfTen(5);
+ Assert.assertEquals("300001.415926", resultDec.toString());
+ Assert.assertEquals(6, resultDec.scale());
+ Assert.assertEquals(6, resultDec.integerDigitCount());
+ resultDec = dec.scaleByPowerOfTen(18);
+ Assert.assertEquals("3000014159260000000", resultDec.toString());
+ Assert.assertEquals(0, resultDec.scale());
+ Assert.assertEquals(19, resultDec.integerDigitCount());
+ resultDec = dec.scaleByPowerOfTen(35);
+ Assert.assertEquals("300001415926000000000000000000000000", resultDec.toString());
+ Assert.assertEquals(0, resultDec.scale());
+ Assert.assertEquals(36, resultDec.integerDigitCount());
+ resultDec = dec.scaleByPowerOfTen(37);
+ Assert.assertEquals("30000141592600000000000000000000000000", resultDec.toString());
+ Assert.assertEquals(0, resultDec.scale());
+ Assert.assertEquals(38, resultDec.integerDigitCount());
+ }
+
+ @Test
+ public void testSingleWordDivision() {
+
+ HiveDecimalV1 oldDec1;
+ HiveDecimalV1 oldDec2;
+ HiveDecimalV1 oldResultDec;
+
+ HiveDecimal dec1;
+ HiveDecimal dec2;
+ HiveDecimal resultDec;
+
+ //---------------------------------------------------
+ oldDec1 = HiveDecimalV1.create("839293");
+ oldDec2 = HiveDecimalV1.create("8");
+ oldResultDec = oldDec1.divide(oldDec2);
+ Assert.assertEquals("104911.625", oldResultDec.toString());
+ //---------------------------------------------------
+ dec1 = HiveDecimal.create("839293");
+ dec2 = HiveDecimal.create("8");
+ resultDec = dec1.divide(dec2);
+ Assert.assertEquals("104911.625", resultDec.toString()); // UNDONE
+
+ //---------------------------------------------------
+ oldDec1 = HiveDecimalV1.create("1");
+ oldDec2 = HiveDecimalV1.create("3");
+ oldResultDec = oldDec1.divide(oldDec2);
+ Assert.assertEquals("0.33333333333333333333333333333333333333", oldResultDec.toString());
+ //---------------------------------------------------
+ dec1 = HiveDecimal.create("1");
+ dec2 = HiveDecimal.create("3");
+ resultDec = dec1.divide(dec2);
+ Assert.assertEquals("0.33333333333333333333333333333333333333", resultDec.toString()); // UNDONE
+
+ //---------------------------------------------------
+ oldDec1 = HiveDecimalV1.create("1");
+ oldDec2 = HiveDecimalV1.create("9");
+ oldResultDec = oldDec1.divide(oldDec2);
+ Assert.assertEquals("0.11111111111111111111111111111111111111", oldResultDec.toString());
+ //---------------------------------------------------
+ dec1 = HiveDecimal.create("1");
+ dec2 = HiveDecimal.create("9");
+ resultDec = dec1.divide(dec2);
+ Assert.assertEquals("0.11111111111111111111111111111111111111", resultDec.toString()); // UNDONE
+
+ //---------------------------------------------------
+ oldDec1 = HiveDecimalV1.create("22");
+ oldDec2 = HiveDecimalV1.create("7");
+ oldResultDec = oldDec1.divide(oldDec2);
+ Assert.assertEquals("3.1428571428571428571428571428571428571", oldResultDec.toString());
+ //---------------------------------------------------
+ dec1 = HiveDecimal.create("22");
+ dec2 = HiveDecimal.create("7");
+ resultDec = dec1.divide(dec2);
+ Assert.assertEquals("3.1428571428571428571428571428571428571", resultDec.toString()); // UNDONE
+
+ //---------------------------------------------------
+ oldDec1 = HiveDecimalV1.create("1");
+ oldDec2 = HiveDecimalV1.create("81");
+ oldResultDec = oldDec1.divide(oldDec2);
+ Assert.assertEquals("0.01234567901234567901234567901234567901", oldResultDec.toString());
+ //---------------------------------------------------
+ dec1 = HiveDecimal.create("1");
+ dec2 = HiveDecimal.create("81");
+ resultDec = dec1.divide(dec2);
+ Assert.assertEquals("0.01234567901234567901234567901234567901", resultDec.toString()); // UNDONE
+
+ //---------------------------------------------------
+ oldDec1 = HiveDecimalV1.create("425");
+ oldDec2 = HiveDecimalV1.create("1000000000000000");
+ oldResultDec = oldDec1.divide(oldDec2);
+ Assert.assertEquals("0.000000000000425", oldResultDec.toString());
+ //---------------------------------------------------
+ dec1 = HiveDecimal.create("425");
+ dec2 = HiveDecimal.create("1000000000000000");
+ resultDec = dec1.divide(dec2);
+ Assert.assertEquals("0.000000000000425", resultDec.toString()); // UNDONE
+
+ //---------------------------------------------------
+ oldDec1 = HiveDecimalV1.create("0.000000000088");
+ oldDec2 = HiveDecimalV1.create("1000000000000000");
+ oldResultDec = oldDec1.divide(oldDec2);
+ Assert.assertEquals("0.000000000000000000000000088", oldResultDec.toString());
+ Assert.assertEquals(27, oldResultDec.scale());
+ //---------------------------------------------------
+ dec1 = HiveDecimal.create("0.000000000088");
+ dec2 = HiveDecimal.create("1000000000000000");
+ resultDec = dec1.divide(dec2);
+ Assert.assertEquals("0.000000000000000000000000088", resultDec.toString()); // UNDONE
+ Assert.assertEquals(27, resultDec.scale());
+ }
+
+ @Test
+ public void testDivide() {
+ HiveDecimal dec1 = HiveDecimal.create("3.14");
+ HiveDecimal dec2 = HiveDecimal.create("3");
+ Assert.assertNotNull(dec1.divide(dec2));
+
+ dec1 = HiveDecimal.create("15");
+ dec2 = HiveDecimal.create("5");
+ Assert.assertEquals("3", dec1.divide(dec2).toString());
+
+ dec1 = HiveDecimal.create("3.140");
+ dec2 = HiveDecimal.create("1.00");
+ Assert.assertEquals("3.14", dec1.divide(dec2).toString());
+ }
+
+ @Test
+ public void testPlus() {
+
+ HiveDecimalV1 oldDec;
+ HiveDecimalV1 oldDec2;
+ HiveDecimalV1 oldResultDec;
+
+ HiveDecimal dec;
+ HiveDecimal dec1;
+ HiveDecimal dec2;
+ HiveDecimal resultDec;
+
+ String decStr;
+ String decStr2;
+
+ dec1 = HiveDecimal.create("3.140");
+ dec1.validate();
+ dec2 = HiveDecimal.create("1.00");
+ dec2.validate();
+ resultDec = dec1.add(dec2);
+ resultDec.validate();
+ Assert.assertEquals("4.14", resultDec.toString());
+
+ decStr = "3.140";
+ decStr2 = "1.00";
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create(decStr);
+ oldDec2 = HiveDecimalV1.create(decStr2);
+ oldResultDec = oldDec.add(oldDec2);
+ Assert.assertEquals("4.14", oldResultDec.toString());
+ //---------------------------------------------------
+ dec = HiveDecimal.create(decStr);
+ assertTrue(dec != null);
+ dec.validate();
+ dec2 = HiveDecimal.create(decStr2);
+ assertTrue(dec2 != null);
+ dec2.validate();
+ resultDec = dec.add(dec2);
+ assertTrue(resultDec != null);
+ resultDec.validate();
+ Assert.assertEquals("4.14", resultDec.toString());
+ Assert.assertEquals(1, resultDec.integerDigitCount());
+
+ decStr = "3.140";
+ decStr2 = "1.00000008733";
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create(decStr);
+ oldDec2 = HiveDecimalV1.create(decStr2);
+ oldResultDec = oldDec.add(oldDec2);
+ Assert.assertEquals("4.14000008733", oldResultDec.toString());
+ //---------------------------------------------------
+ dec = HiveDecimal.create(decStr);
+ assertTrue(dec != null);
+ dec.validate();
+ dec2 = HiveDecimal.create(decStr2);
+ assertTrue(dec2 != null);
+ dec2.validate();
+ resultDec = dec.add(dec2);
+ assertTrue(resultDec != null);
+ resultDec.validate();
+ Assert.assertEquals("4.14000008733", resultDec.toString());
+ Assert.assertEquals(1, resultDec.integerDigitCount());
+
+ decStr = "3.140";
+ decStr2 = "1.00000000000000000008733";
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create(decStr);
+ oldDec2 = HiveDecimalV1.create(decStr2);
+ oldResultDec = oldDec.add(oldDec2);
+ Assert.assertEquals("4.14000000000000000008733", oldResultDec.toString());
+ //---------------------------------------------------
+ dec = HiveDecimal.create(decStr);
+ assertTrue(dec != null);
+ dec.validate();
+ dec2 = HiveDecimal.create(decStr2);
+ assertTrue(dec2 != null);
+ dec2.validate();
+ resultDec = dec.add(dec2);
+ assertTrue(resultDec != null);
+ resultDec.validate();
+ Assert.assertEquals("4.14000000000000000008733", resultDec.toString());
+ Assert.assertEquals(1, resultDec.integerDigitCount());
+
+ decStr = "30000000000.140";
+ decStr2 = "1.00000000000000000008733";
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create(decStr);
+ oldDec2 = HiveDecimalV1.create(decStr2);
+ oldResultDec = oldDec.add(oldDec2);
+ Assert.assertEquals("30000000001.14000000000000000008733", oldResultDec.toString());
+ //---------------------------------------------------
+ dec = HiveDecimal.create(decStr);
+ assertTrue(dec != null);
+ dec.validate();
+ dec2 = HiveDecimal.create(decStr2);
+ assertTrue(dec2 != null);
+ dec2.validate();
+ resultDec = dec.add(dec2);
+ assertTrue(resultDec != null);
+ resultDec.validate();
+ Assert.assertEquals("30000000001.14000000000000000008733", resultDec.toString());
+ // Assert.assertEquals(1, resultDec.integerDigitCount());
+
+ decStr = "300000000000000.140";
+ decStr2 = "1.00000000000000000008733";
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create(decStr);
+ oldDec2 = HiveDecimalV1.create(decStr2);
+ oldResultDec = oldDec.add(oldDec2);
+ Assert.assertEquals("300000000000001.14000000000000000008733", oldResultDec.toString());
+ //---------------------------------------------------
+ dec = HiveDecimal.create(decStr);
+ assertTrue(dec != null);
+ dec.validate();
+ dec2 = HiveDecimal.create(decStr2);
+ assertTrue(dec2 != null);
+ dec2.validate();
+ resultDec = dec.add(dec2);
+ assertTrue(resultDec != null);
+ resultDec.validate();
+ Assert.assertEquals("300000000000001.14000000000000000008733", resultDec.toString());
+ // Assert.assertEquals(1, resultDec.integerDigitCount());
+
+ // Edge case?
+ decStr = "3000000000000000.140";
+ decStr2 = "1.00000000000000000008733";
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create(decStr);
+ oldDec2 = HiveDecimalV1.create(decStr2);
+ oldResultDec = oldDec.add(oldDec2);
+ Assert.assertEquals("3000000000000001.1400000000000000000873", oldResultDec.toString());
+ //---------------------------------------------------
+ dec = HiveDecimal.create(decStr);
+ assertTrue(dec != null);
+ dec.validate();
+ dec2 = HiveDecimal.create(decStr2);
+ assertTrue(dec2 != null);
+ dec2.validate();
+ resultDec = dec.add(dec2);
+ assertTrue(resultDec != null);
+ resultDec.validate();
+ Assert.assertEquals("3000000000000001.1400000000000000000873", resultDec.toString());
+ // Assert.assertEquals(1, resultDec.integerDigitCount());
+
+ decStr = "300000000000000000000000.14";
+ decStr2 = "0.0000055555555550008733";
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create(decStr);
+ oldDec2 = HiveDecimalV1.create(decStr2);
+ oldResultDec = oldDec.add(oldDec2);
+ Assert.assertEquals("300000000000000000000000.14000555555556", oldResultDec.toString());
+ //---------------------------------------------------
+ dec = HiveDecimal.create(decStr);
+ assertTrue(dec != null);
+ dec.validate();
+ dec2 = HiveDecimal.create(decStr2);
+ assertTrue(dec2 != null);
+ dec2.validate();
+ resultDec = dec.add(dec2);
+ assertTrue(resultDec != null);
+ resultDec.validate();
+ Assert.assertEquals("300000000000000000000000.14000555555556", resultDec.toString());
+ // Assert.assertEquals(1, resultDec.integerDigitCount());
+
+ decStr = "300000000000000000000000.14";
+ decStr2 = "0.000005555555555000873355";
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create(decStr);
+ oldDec2 = HiveDecimalV1.create(decStr2);
+ oldResultDec = oldDec.add(oldDec2);
+ Assert.assertEquals("300000000000000000000000.14000555555556", oldResultDec.toString());
+ //---------------------------------------------------
+ dec = HiveDecimal.create(decStr);
+ assertTrue(dec != null);
+ dec.validate();
+ dec2 = HiveDecimal.create(decStr2);
+ assertTrue(dec2 != null);
+ dec2.validate();
+ resultDec = dec.add(dec2);
+ assertTrue(resultDec != null);
+ resultDec.validate();
+ Assert.assertEquals("300000000000000000000000.14000555555556", resultDec.toString());
+ // Assert.assertEquals(1, resultDec.integerDigitCount());
+
+
+
+ // Example from HiveDecimal.add header comments.
+ decStr = "598575157855521918987423259.94094";
+ decStr2 = "0.0000000000006711991169422033";
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create(decStr);
+ oldDec2 = HiveDecimalV1.create(decStr2);
+ oldResultDec = oldDec.add(oldDec2);
+ Assert.assertEquals("598575157855521918987423259.94094", oldResultDec.toString());
+ //---------------------------------------------------
+ dec = HiveDecimal.create(decStr);
+ assertTrue(dec != null);
+ dec.validate();
+ dec2 = HiveDecimal.create(decStr2);
+ assertTrue(dec2 != null);
+ dec2.validate();
+ resultDec = dec.add(dec2);
+ assertTrue(resultDec != null);
+ resultDec.validate();
+ Assert.assertEquals("598575157855521918987423259.94094", resultDec.toString());
+ Assert.assertEquals(27, resultDec.integerDigitCount());
+
+ decStr = "598575157855521918987423259.94094";
+ decStr2 = "0.5555555555556711991169422033";
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create(decStr);
+ oldDec2 = HiveDecimalV1.create(decStr2);
+ oldResultDec = oldDec.add(oldDec2);
+ Assert.assertEquals("598575157855521918987423260.49649555556", oldResultDec.toString());
+ //---------------------------------------------------
+ dec = HiveDecimal.create(decStr);
+ assertTrue(dec != null);
+ dec.validate();
+ dec2 = HiveDecimal.create(decStr2);
+ assertTrue(dec2 != null);
+ dec2.validate();
+ resultDec = dec.add(dec2);
+ assertTrue(resultDec != null);
+ resultDec.validate();
+ Assert.assertEquals("598575157855521918987423260.49649555556", resultDec.toString());
+ Assert.assertEquals(27, resultDec.integerDigitCount());
+
+ decStr = "199999999.99995";
+ decStr2 = "100000000.00005";
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create(decStr);
+ oldDec2 = HiveDecimalV1.create(decStr2);
+ oldResultDec = oldDec.add(oldDec2);
+ Assert.assertEquals("300000000", oldResultDec.toString());
+ //---------------------------------------------------
+ dec = HiveDecimal.create(decStr);
+ assertTrue(dec != null);
+ dec.validate();
+ dec2 = HiveDecimal.create(decStr2);
+ assertTrue(dec2 != null);
+ dec2.validate();
+ resultDec = dec.add(dec2);
+ assertTrue(resultDec != null);
+ resultDec.validate();
+ Assert.assertEquals("300000000", resultDec.toString());
+ Assert.assertEquals(9, resultDec.integerDigitCount());
+
+ dec1 = HiveDecimal.create("99999999999999999999999999999999999999");
+ dec1.validate();
+ Assert.assertEquals(38, dec1.integerDigitCount());
+ dec2 = HiveDecimal.create("1");
+ dec2.validate();
+ Assert.assertNull(dec1.add(dec2));
+ }
+
+ @Test
+ public void testAdd() {
+
+ HiveDecimalV1 oldDec;
+ HiveDecimalV1 oldDec2;
+ HiveDecimalV1 oldResultDec;
+
+ HiveDecimal dec;
+ HiveDecimal dec2;
+ HiveDecimal resultDec;
+
+ // Use the example from HIVE-13423 where the integer digits of the result exceed the
+ // enforced precision/scale.
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create("98765432109876543210.12345");
+ oldResultDec = oldDec.add(oldDec);
+ Assert.assertEquals("197530864219753086420.2469", oldResultDec.toString());
+ oldResultDec = HiveDecimalV1.enforcePrecisionScale(oldResultDec, 38, 18);
+ Assert.assertTrue(oldResultDec == null);
+ //---------------------------------------------------
+ dec = HiveDecimal.create("98765432109876543210.12345");
+ assertTrue(dec != null);
+ dec.validate();
+ resultDec = dec.add(dec);
+ assertTrue(resultDec != null);
+ resultDec.validate();
+ Assert.assertEquals("197530864219753086420.2469", resultDec.toString());
+ // Assert.assertEquals(21, resultDec.integerDigitCount());
+ resultDec = HiveDecimal.enforcePrecisionScale(resultDec, 38, 18);
+ Assert.assertTrue(resultDec == null);
+
+ // Make sure zero trimming doesn't extend into the integer digits.
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create("199999999.99995");
+ oldDec2 = HiveDecimalV1.create("100000000.00005");
+ oldResultDec = oldDec.add(oldDec2);
+ Assert.assertEquals("300000000", oldResultDec.toString());
+ //---------------------------------------------------
+ dec = HiveDecimal.create("199999999.99995");
+ assertTrue(dec != null);
+ dec.validate();
+ dec2 = HiveDecimal.create("100000000.00005");
+ assertTrue(dec2 != null);
+ dec2.validate();
+ resultDec = dec.add(dec2);
+ assertTrue(resultDec != null);
+ resultDec.validate();
+ Assert.assertEquals("300000000", resultDec.toString());
+ Assert.assertEquals(9, resultDec.integerDigitCount());
+ }
+
+ @Test
+ public void testMinus() {
+
+ HiveDecimalV1 oldDec;
+ HiveDecimalV1 oldDec2;
+ HiveDecimalV1 oldResultDec;
+
+ HiveDecimal dec;
+ HiveDecimal dec1;
+ HiveDecimal dec2;
+ HiveDecimal resultDec;
+
+ String decStr;
+ String decStr2;
+
+ dec1 = HiveDecimal.create("3.140");
+ dec1.validate();
+ dec2 = HiveDecimal.create("1.00");
+ dec2.validate();
+ resultDec = dec1.add(dec2);
+ resultDec.validate();
+ Assert.assertEquals("4.14", resultDec.toString());
+
+ decStr = "3.140";
+ decStr2 = "1.00";
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create(decStr);
+ oldDec2 = HiveDecimalV1.create(decStr2);
+ oldResultDec = oldDec.subtract(oldDec2);
+ Assert.assertEquals("2.14", oldResultDec.toString());
+ //---------------------------------------------------
+ dec = HiveDecimal.create(decStr);
+ assertTrue(dec != null);
+ dec.validate();
+ dec2 = HiveDecimal.create(decStr2);
+ assertTrue(dec2 != null);
+ dec2.validate();
+ resultDec = dec.subtract(dec2);
+ assertTrue(resultDec != null);
+ resultDec.validate();
+ Assert.assertEquals("2.14", resultDec.toString());
+ // Assert.assertEquals(1, resultDec.integerDigitCount());
+
+ decStr = "3.140";
+ decStr2 = "1.00000008733";
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create(decStr);
+ oldDec2 = HiveDecimalV1.create(decStr2);
+ oldResultDec = oldDec.subtract(oldDec2);
+ Assert.assertEquals("2.13999991267", oldResultDec.toString());
+ //---------------------------------------------------
+ dec = HiveDecimal.create(decStr);
+ assertTrue(dec != null);
+ dec.validate();
+ dec2 = HiveDecimal.create(decStr2);
+ assertTrue(dec2 != null);
+ dec2.validate();
+ resultDec = dec.subtract(dec2);
+ assertTrue(resultDec != null);
+ resultDec.validate();
+ Assert.assertEquals("2.13999991267", resultDec.toString());
+ // Assert.assertEquals(1, resultDec.integerDigitCount());
+
+ decStr = "3.140";
+ decStr2 = "1.00000000000000000008733";
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create(decStr);
+ oldDec2 = HiveDecimalV1.create(decStr2);
+ oldResultDec = oldDec.subtract(oldDec2);
+ Assert.assertEquals("2.13999999999999999991267", oldResultDec.toString());
+ //---------------------------------------------------
+ dec = HiveDecimal.create(decStr);
+ assertTrue(dec != null);
+ dec.validate();
+ dec2 = HiveDecimal.create(decStr2);
+ assertTrue(dec2 != null);
+ dec2.validate();
+ resultDec = dec.subtract(dec2);
+ assertTrue(resultDec != null);
+ resultDec.validate();
+ Assert.assertEquals("2.13999999999999999991267", resultDec.toString());
+ // Assert.assertEquals(1, resultDec.integerDigitCount());
+
+ decStr = "30000000000.140";
+ decStr2 = "1.00000000000000000008733";
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create(decStr);
+ oldDec2 = HiveDecimalV1.create(decStr2);
+ oldResultDec = oldDec.subtract(oldDec2);
+ Assert.assertEquals("29999999999.13999999999999999991267", oldResultDec.toString());
+ //---------------------------------------------------
+ dec = HiveDecimal.create(decStr);
+ assertTrue(dec != null);
+ dec.validate();
+ dec2 = HiveDecimal.create(decStr2);
+ assertTrue(dec2 != null);
+ dec2.validate();
+ resultDec = dec.subtract(dec2);
+ assertTrue(resultDec != null);
+ resultDec.validate();
+ Assert.assertEquals("29999999999.13999999999999999991267", resultDec.toString());
+ // Assert.assertEquals(1, resultDec.integerDigitCount());
+
+ decStr = "300000000000000.140";
+ decStr2 = "1.00000000000000000008733";
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create(decStr);
+ oldDec2 = HiveDecimalV1.create(decStr2);
+ oldResultDec = oldDec.subtract(oldDec2);
+ Assert.assertEquals("299999999999999.13999999999999999991267", oldResultDec.toString());
+ //---------------------------------------------------
+ dec = HiveDecimal.create(decStr);
+ assertTrue(dec != null);
+ dec.validate();
+ dec2 = HiveDecimal.create(decStr2);
+ assertTrue(dec2 != null);
+ dec2.validate();
+ resultDec = dec.subtract(dec2);
+ assertTrue(resultDec != null);
+ resultDec.validate();
+ Assert.assertEquals("299999999999999.13999999999999999991267", resultDec.toString());
+ // Assert.assertEquals(1, resultDec.integerDigitCount());
+
+ // Edge case?
+ decStr = "3000000000000000.140";
+ decStr2 = "1.00000000000000000008733";
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create(decStr);
+ oldDec2 = HiveDecimalV1.create(decStr2);
+ oldResultDec = oldDec.subtract(oldDec2);
+ Assert.assertEquals("2999999999999999.1399999999999999999127", oldResultDec.toString());
+ //---------------------------------------------------
+ dec = HiveDecimal.create(decStr);
+ assertTrue(dec != null);
+ dec.validate();
+ dec2 = HiveDecimal.create(decStr2);
+ assertTrue(dec2 != null);
+ dec2.validate();
+ resultDec = dec.subtract(dec2);
+ assertTrue(resultDec != null);
+ resultDec.validate();
+ Assert.assertEquals("2999999999999999.1399999999999999999127", resultDec.toString());
+ // Assert.assertEquals(1, resultDec.integerDigitCount());
+
+ decStr = "300000000000000000000000.14";
+ decStr2 = "0.0000055555555550008733";
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create(decStr);
+ oldDec2 = HiveDecimalV1.create(decStr2);
+ oldResultDec = oldDec.subtract(oldDec2);
+ Assert.assertEquals("300000000000000000000000.13999444444444", oldResultDec.toString());
+ //---------------------------------------------------
+ dec = HiveDecimal.create(decStr);
+ assertTrue(dec != null);
+ dec.validate();
+ dec2 = HiveDecimal.create(decStr2);
+ assertTrue(dec2 != null);
+ dec2.validate();
+ resultDec = dec.subtract(dec2);
+ assertTrue(resultDec != null);
+ resultDec.validate();
+ Assert.assertEquals("300000000000000000000000.13999444444444", resultDec.toString());
+ // Assert.assertEquals(1, resultDec.integerDigitCount());
+
+ decStr = "300000000000000000000000.14";
+ decStr2 = "0.000005555555555000873355";
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create(decStr);
+ oldDec2 = HiveDecimalV1.create(decStr2);
+ oldResultDec = oldDec.subtract(oldDec2);
+ Assert.assertEquals("300000000000000000000000.13999444444444", oldResultDec.toString());
+ //---------------------------------------------------
+ dec = HiveDecimal.create(decStr);
+ assertTrue(dec != null);
+ dec.validate();
+ dec2 = HiveDecimal.create(decStr2);
+ assertTrue(dec2 != null);
+ dec2.validate();
+ resultDec = dec.subtract(dec2);
+ assertTrue(resultDec != null);
+ resultDec.validate();
+ Assert.assertEquals("300000000000000000000000.13999444444444", resultDec.toString());
+ // Assert.assertEquals(1, resultDec.integerDigitCount());
+
+ // Example from HiveDecimal.subtract header comments.
+ decStr = "598575157855521918987423259.94094";
+ decStr2 = "0.0000000000006711991169422033";
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create(decStr);
+ oldDec2 = HiveDecimalV1.create(decStr2);
+ oldResultDec = oldDec.subtract(oldDec2);
+ Assert.assertEquals("598575157855521918987423259.94094", oldResultDec.toString());
+ //---------------------------------------------------
+ dec = HiveDecimal.create(decStr);
+ assertTrue(dec != null);
+ dec.validate();
+ dec2 = HiveDecimal.create(decStr2);
+ assertTrue(dec2 != null);
+ dec2.validate();
+ resultDec = dec.subtract(dec2);
+ assertTrue(resultDec != null);
+ resultDec.validate();
+ Assert.assertEquals("598575157855521918987423259.94094", resultDec.toString());
+ // Assert.assertEquals(1, resultDec.integerDigitCount());
+
+ decStr = "598575157855521918987423259.94094";
+ decStr2 = "0.5555555555556711991169422033";
+ //---------------------------------------------------
+ oldDec = HiveDecimalV1.create(decStr);
+ oldDec2 = HiveDecimalV1.create(decStr2);
+ oldResultDec = oldDec.subtract(oldDec2);
+ Assert.assertEquals("598575157855521918987423259.38538444444", oldResultDec.toString());
+ //---------------------------------------------------
+ dec = HiveDecimal.create(decStr);
+ assertTrue(dec != null);
+ dec.validate();
+ dec2 = HiveDecimal.create(decStr2);
+ assertTrue(dec2 != null);
+ dec2.validate();
+ resultDec = dec.subtract(dec2);
+ assertTrue(resultDec != null);
+ resultDec.validate();
+ Assert.assertEquals("598575157855521918987423259.38538444444", resultDec.toString());
+ // Assert.assertEquals(1, resultDec.integerDigitCount());
+ }
+
+ @Test
+ public void testSubtract() {
+ HiveDecimal dec1 = HiveDecimal.create("3.140");
+ assertTrue(dec1 != null);
+ dec1.validate();
+ HiveDecimal dec2 = HiveDecimal.create("1.00");
+ assertTrue(dec2 != null);
+ dec2.validate();
+ HiveDecimal result = dec1.subtract(dec2);
+ assertTrue(result != null);
+ result.validate();
+ Assert.assertEquals("2.14", result.toString());
+
+ dec1 = HiveDecimal.create("0.00001786135888657847525803");
+ assertTrue(dec1 != null);
+ dec1.validate();
+ dec2 = HiveDecimal.create("3.0000123456789");
+ assertTrue(dec2 != null);
+ dec2.validate();
+ result = dec1.subtract(dec2);
+ assertTrue(result != null);
+ result.validate();
+ Assert.assertEquals("-2.99999448432001342152474197", result.toString());
+ }
+
+ @Test
+ public void testPosMod() {
+ HiveDecimal hd1 = HiveDecimal.create("-100.91");
+ assertTrue(hd1 != null);
+ hd1.validate();
+ HiveDecimal hd2 = HiveDecimal.create("9.8");
+ assertTrue(hd2 != null);
+ hd2.validate();
+ HiveDecimal dec = hd1.remainder(hd2).add(hd2).remainder(hd2);
+ assertTrue(dec != null);
+ dec.validate();
+ Assert.assertEquals("6.89", dec.toString());
+ }
+
+ @Test
+ public void testHashCode() {
+ Assert.assertEquals(HiveDecimal.create("9").hashCode(), HiveDecimal.create("9.00").hashCode());
+ Assert.assertEquals(HiveDecimal.create("0").hashCode(), HiveDecimal.create("0.00").hashCode());
+ }
+
+ @Test
+ public void testException() {
+ HiveDecimal dec = HiveDecimal.create("3.1415.926");
+ Assert.assertNull(dec);
+ dec = HiveDecimal.create("3abc43");
+ Assert.assertNull(dec);
+ }
+
+ @Test
+ public void testBinaryConversion() {
+ Random r = new Random(2399);
+ for (String decString : specialDecimalStrings) {
+ doTestBinaryConversion(decString, r);
+ }
+ }
+
+ private void doTestBinaryConversion(String num, Random r) {
+ int scale = r.nextInt(HiveDecimal.MAX_SCALE);
+ HiveDecimal dec = HiveDecimal.create(num);
+ if (dec == null) {
+ return;
+ }
+ byte[] d = dec.setScale(scale).unscaledValue().toByteArray();
+ HiveDecimal roundedDec = dec.setScale(scale, HiveDecimal.ROUND_HALF_UP);
+ Assert.assertEquals(roundedDec, HiveDecimal.create(new BigInteger(d), scale));
+ }
+
+//------------------------------------------------------------------------------------------------
+
+ @Test
+ public void testDecimalsWithOneOne() {
+ doTestDecimalsWithPrecisionScale(decimal_1_1_txt, 1, 1);
+ }
+
+ @Test
+ public void testDecimalsWithKv7Keys() {
+ doTestDecimalsWithPrecisionScale(kv7_txt_keys, 38, 18);
+ }
+
+ public void doTestDecimalsWithPrecisionScale(String[] decStrings, int precision, int scale) {
+
+ HiveDecimalV1 oldSum = HiveDecimalV1.create(0);
+ HiveDecimalWritable sum = new HiveDecimalWritable(0);
+
+ for (int i = 0; i < decStrings.length; i++) {
+
+ String string = decStrings[i];
+
+ HiveDecimalV1 oldDec = HiveDecimalV1.create(string);
+
+ HiveDecimalV1 resultOldDec;
+ if (oldDec == null) {
+ resultOldDec = null;
+ } else {
+ resultOldDec = HiveDecimalV1.enforcePrecisionScale(oldDec, precision, scale);
+ }
+
+ HiveDecimal dec = HiveDecimal.create(string);
+
+ if (oldDec == null) {
+ Assert.assertTrue(dec == null);
+ continue;
+ }
+ HiveDecimal resultDec = HiveDecimal.enforcePrecisionScale(dec, precision, scale);
+ if (resultOldDec == null) {
+ Assert.assertTrue(resultDec == null);
+ continue;
+ }
+
+ Assert.assertEquals(resultOldDec.toString(), resultDec.toString());
+ Assert.assertEquals(resultOldDec.toFormatString(scale), resultDec.toFormatString(scale));
+
+ oldSum = oldSum.add(resultOldDec);
+ sum.mutateAdd(resultDec);
+ }
+
+ Assert.assertEquals(oldSum.toString(), sum.toString());
+ }
+
+//------------------------------------------------------------------------------------------------
+
+ @Test
+ public void testDecimalsWithOneOneWritable() {
+ doTestDecimalsWithPrecisionScaleWritable(decimal_1_1_txt, 1, 1);
+ }
+
+ @Test
+ public void testDecimalsWithKv7KeysWritable() {
+ doTestDecimalsWithPrecisionScaleWritable(kv7_txt_keys, 38, 18);
+ }
+
+ public void doTestDecimalsWithPrecisionScaleWritable(String[] decStrings, int precision, int scale) {
+
+ HiveDecimalV1 oldSum = HiveDecimalV1.create(0);
+ HiveDecimalWritable sum = new HiveDecimalWritable(0);
+
+ for (int i = 0; i < decStrings.length; i++) {
+ String string = decStrings[i];
+
+ HiveDecimalV1 oldDec = HiveDecimalV1.create(string);
+ HiveDecimalV1 resultOldDec;
+ if (oldDec == null) {
+ resultOldDec = null;
+ } else {
+ resultOldDec = HiveDecimalV1.enforcePrecisionScale(oldDec, precision, scale);
+ }
+
+ HiveDecimalWritable decWritable = new HiveDecimalWritable(string);
+ if (oldDec == null) {
+ Assert.assertTrue(!decWritable.isSet());
+ continue;
+ }
+ decWritable.mutateEnforcePrecisionScale(precision, scale);;
+ if (resultOldDec == null) {
+ Assert.assertTrue(!decWritable.isSet());
+ continue;
+ }
+
+ Assert.assertEquals(resultOldDec.toString(), decWritable.toString());
+ Assert.assertEquals(resultOldDec.toFormatString(scale), decWritable.toFormatString(scale));
+
+ oldSum = oldSum.add(resultOldDec);
+ sum.mutateAdd(decWritable);
+ }
+
+ Assert.assertEquals(oldSum.toString(), sum.toString());
+ }
+
+ //------------------------------------------------------------------------------------------------
+
+ @Test
+ public void testSort() {
+ doTestSort(decimal_1_1_txt);
+ }
+
+ @Test
+ public void testSortSpecial() {
+ doTestSort(specialDecimalStrings);
+ }
+
+ @Test
+ public void testSortRandom() {
+ Random r = new Random(14434);
+ for (BigDecimalFlavor bigDecimalFlavor : BigDecimalFlavor.values()) {
+ doTestSortRandom(r, standardAlphabet, bigDecimalFlavor);
+ }
+ for (BigDecimalFlavor bigDecimalFlavor : BigDecimalFlavor.values()) {
+ for (String sparseAlphabet : sparseAlphabets) {
+ doTestSortRandom(r, sparseAlphabet, bigDecimalFlavor);
+ }
+ }
+ }
+
+ public void doTestSortRandom(Random r, String digitAlphabet, BigDecimalFlavor bigDecimalFlavor) {
+ String[] randomStrings = new String[POUND_FACTOR];
+
+ for (int i = 0; i < POUND_FACTOR; i++) {
+ BigDecimal bigDecimal = randHiveBigDecimal(r, digitAlphabet, bigDecimalFlavor);
+
+ randomStrings[i] = bigDecimal.toString();
+ }
+
+ doTestSort(randomStrings);
+ }
+
+ public void doTestSort(String[] decStrings) {
+
+ HiveDecimalV1[] oldDecSortArray = new HiveDecimalV1[decStrings.length];
+ HiveDecimal[] decSortArray = new HiveDecimal[decStrings.length];
+
+ int count = 0;
+ for (int i = 0; i < decStrings.length; i++) {
+ String string = decStrings[i];
+
+ HiveDecimalV1 oldDec = HiveDecimalV1.create(string);
+ if (oldDec == null) {
+ continue;
+ }
+ if (isTenPowerBug(oldDec.toString())) {
+ continue;
+ }
+ oldDecSortArray[count] = oldDec;
+
+ HiveDecimal dec = HiveDecimal.create(string);
+ if (dec == null) {
+ Assert.fail();
+ }
+ decSortArray[count] = dec;
+ count++;
+ }
+
+ oldDecSortArray = Arrays.copyOf(oldDecSortArray, count);
+ decSortArray = Arrays.copyOf(decSortArray, count);
+
+ Arrays.sort(oldDecSortArray);
+ Arrays.sort(decSortArray);
+
+ for (int i = 0; i < count; i++) {
+ String oldDecString = oldDecSortArray[i].toString();
+ String decString = decSortArray[i].toString();
+
+ if (!oldDecString.equals(decString)) {
+ Assert.fail();
+ }
+ }
+ }
+
+ //------------------------------------------------------------------------------------------------
+
+ @Test
+ public void testRandomCreateFromBigDecimal() {
+ Random r = new Random(14434);
+ for (BigDecimalFlavor bigDecimalFlavor : BigDecimalFlavor.values()) {
+ doTestRandomCreateFromBigDecimal(r, standardAlphabet, bigDecimalFlavor);
+ }
+ for (BigDecimalFlavor bigDecimalFlavor : BigDecimalFlavor.values()) {
+ for (String sparseAlphabet : sparseAlphabets) {
+ doTestRandomCreateFromBigDecimal(r, sparseAlphabet, bigDecimalFlavor);
+ }
+ }
+ }
+
+ private void doTestRandomCreateFromBigDecimal(Random r, String digitAlphabet, BigDecimalFlavor bigDecimalFlavor) {
+
+ for (int i = 0; i < POUND_FACTOR; i++) {
+ BigDecimal bigDecimal = randHiveBigDecimal(r, digitAlphabet, bigDecimalFlavor);
+
+ doTestCreateFromBigDecimal(bigDecimal);
+ }
+ }
+
+ @Test
+ public void testCreateFromBigDecimalSpecial() {
+ for (BigDecimal bigDecimal : specialBigDecimals) {
+ doTestCreateFromBigDecimal(bigDecimal);
+ }
+ }
+
+ private void doTestCreateFromBigDecimal(BigDecimal bigDecimal) {
+
+ HiveDecimalV1 oldDec = HiveDecimalV1.create(bigDecimal);
+ if (oldDec != null && isTenPowerBug(oldDec.toString())) {
+ return;
+ }
+ HiveDecimal dec = HiveDecimal.create(bigDecimal);
+ if (oldDec == null) {
+ assertTrue(dec == null);
+ return;
+ }
+ assertTrue(dec != null);
+ dec.validate();
+
+ Assert.assertEquals(oldDec.toString(), dec.toString());
+ }
+
+ //------------------------------------------------------------------------------------------------
+
+ @Test
+ public void testRandomCreateFromBigDecimalNoRound() {
+ Random r = new Random(14434);
+ for (BigDecimalFlavor bigDecimalFlavor : BigDecimalFlavor.values()) {
+ doTestRandomCreateFromBigDecimalNoRound(r, standardAlphabet, bigDecimalFlavor);
+ }
+ for (BigDecimalFlavor bigDecimalFlavor : BigDecimalFlavor.values()) {
+ for (String sparseAlphabet : sparseAlphabets) {
+ doTestRandomCreateFromBigDecimalNoRound(r, sparseAlphabet, bigDecimalFlavor);
+ }
+ }
+ }
+
+ private void doTestRandomCreateFromBigDecimalNoRound(Random r, String digitAlphabet, BigDecimalFlavor bigDecimalFlavor) {
+
+ for (int i = 0; i < POUND_FACTOR; i++) {
+ BigDecimal bigDecimal = randHiveBigDecimal(r, digitAlphabet, bigDecimalFlavor);
+
+ doTestCreateFromBigDecimalNoRound(bigDecimal);
+ }
+ }
+
+ @Test
+ public void testCreateFromBigDecimalNoRoundSpecial() {
+ for (BigDecimal bigDecimal : specialBigDecimals) {
+ doTestCreateFromBigDecimalNoRound(bigDecimal);
+ }
+ }
+
+ private void doTestCreateFromBigDecimalNoRound(BigDecimal bigDecimal) {
+
+ HiveDecimalV1 oldDec = HiveDecimalV1.create(bigDecimal, /* allowRounding */ false);
+ HiveDecimal dec = HiveDecimal.create(bigDecimal, /* allowRounding */ false);
+ if (oldDec == null) {
+ assertTrue(dec == null);
+ return;
+ }
+ if (dec == null) {
+ Assert.fail();
+ }
+ dec.validate();
+
+ Assert.assertEquals(oldDec.toString(), dec.toString());
+
+ }
+
+ //------------------------------------------------------------------------------------------------
+
+ @Test
+ public void testCreateFromBigDecimalNegativeScaleSpecial() {
+ Random r = new Random(223965);
+ for (BigDecimal bigDecimal : specialBigDecimals) {
+ int negativeScale = -(0 + r.nextInt(38 + 1));
+ bigDecimal = bigDecimal.setScale(negativeScale, BigDecimal.ROUND_HALF_UP);
+ doTestCreateFromBigDecimalNegativeScale(bigDecimal);
+ }
+ }
+
+ private void doTestCreateFromBigDecimalNegativeScale(BigDecimal bigDecimal) {
+
+ HiveDecimalV1 oldDec = HiveDecimalV1.create(bigDecimal);
+ HiveDecimal dec = HiveDecimal.create(bigDecimal);
+ if (oldDec == null) {
+ assertTrue(dec == null);
+ return;
+ }
+ assertTrue(dec != null);
+ dec.validate();
+
+ Assert.assertEquals(oldDec.toString(), dec.toString());
+ }
+
+ //------------------------------------------------------------------------------------------------
+
+ @Test
+ public void testRandomCreateFromBigInteger() {
+ doTestRandomCreateFromBigInteger(standardAlphabet);
+ }
+
+ @Test
+ public void testRandomCreateFromBigIntegerSparse() {
+ for (String digitAlphabet : sparseAlphabets) {
+ doTestRandomCreateFromBigInteger(digitAlphabet);
+ }
+ }
+
+ private void doTestRandomCreateFromBigInteger(String digitAlphabet) {
+
+ Random r = new Random(11241);
+ for (int i = 0; i < POUND_FACTOR; i++) {
+ BigInteger bigInteger = randHiveBigInteger(r, digitAlphabet);
+
+ doTestCreateFromBigInteger(bigInteger);
+ }
+ }
+
+ @Test
+ public void testCreateFromBigIntegerSpecial() {
+ for (BigDecimal bigDecimal : specialBigDecimals) {
+ doTestCreateFromBigInteger(bigDecimal.unscaledValue());
+ }
+ }
+
+ private void doTestCreateFromBigInteger(BigInteger bigInteger) {
+
+ HiveDecimalV1 oldDec = HiveDecimalV1.create(bigInteger);
+ HiveDecimal dec = HiveDecimal.create(bigInteger);
+ if (oldDec == null) {
+ assertTrue(dec == null);
+ return;
+ }
+ assertTrue(dec != null);
+ dec.validate();
+
+ Assert.assertEquals(oldDec.toString(), dec.toString());
+
+ }
+
+ //------------------------------------------------------------------------------------------------
+
+ @Test
+ public void testRandomCreateFromBigIntegerScale() {
+ doTestRandomCreateFromBigIntegerScale(standardAlphabet, false);
+ }
+
+ @Test
+ public void testRandomCreateFromBigIntegerScaleFractionsOnly() {
+ doTestRandomCreateFromBigIntegerScale(standardAlphabet, true);
+ }
+
+ @Test
+ public void testRandomCreateFromBigIntegerScaleSparse() {
+ for (String digitAlphabet : sparseAlphabets) {
+ doTestRandomCreateFromBigIntegerScale(digitAlphabet, false);
+ }
+ }
+
+ private void doTestRandomCreateFromBigIntegerScale(String digitAlphabet, boolean fractionsOnly) {
+
+ Random r = new Random(4448);
+ for (int i = 0; i < POUND_FACTOR; i++) {
+ BigInteger bigInteger = randHiveBigInteger(r, digitAlphabet);
+
+ int scale;
+ if (fractionsOnly) {
+ scale = 1 + r.nextInt(38);
+ } else {
+ scale = 0 + r.nextInt(38 + 1);
+ }
+
+ doTestCreateFromBigIntegerScale(bigInteger, scale);
+ }
+ }
+
+ @Test
+ public void testCreateFromBigIntegerScaleSpecial() {
+ for (BigDecimal bigDecimal : specialBigDecimals) {
+ doTestCreateFromBigIntegerScale(bigDecimal.unscaledValue(), bigDecimal.scale());
+ }
+ }
+
+ private void doTestCreateFromBigIntegerScale(BigInteger bigInteger, int scale) {
+
+ HiveDecimalV1 oldDec = HiveDecimalV1.create(bigInteger, scale);
+ HiveDecimal dec = HiveDecimal.create(bigInteger, scale);
+ if (oldDec == null) {
+ assertTrue(dec == null);
+ return;
+ }
+ assertTrue(dec != null);
+ dec.validate();
+
+ Assert.assertEquals(oldDec.toString(), dec.toString());
+
+ }
+
+ //------------------------------------------------------------------------------------------------
+
+ @Test
+ public void testRandomSetFromDouble() {
+ Random r = new Random(14434);
+ for (BigDecimalFlavor bigDecimalFlavor : BigDecimalFlavor.values()) {
+ doTestRandomSetFromDouble(r, standardAlphabet, bigDecimalFlavor);
+ }
+ for (BigDecimalFlavor bigDecimalFlavor : BigDecimalFlavor.values()) {
+ for (String sparseAlphabet : sparseAlphabets) {
+ doTestRandomSetFromDouble(r, sparseAlphabet, bigDecimalFlavor);
+ }
+ }
+ }
+
+ private void doTestRandomSetFromDouble(Random r, String digitAlphabet, BigDecimalFlavor bigDecimalFlavor) {
+
+ for (int i = 0; i < POUND_FACTOR; i++) {
+ BigDecimal bigDecimal = randHiveBigDecimal(r, digitAlphabet, bigDecimalFlavor);
+
+ doTestSetFromDouble(bigDecimal.doubleValue());
+ }
+ }
+
+ private void doTestRandomSetFromDouble() {
+
+ Random r = new Random(94762);
+ for (int i = 0; i < POUND_FACTOR; i++) {
+ double randomDouble = r.nextDouble();
+
+ doTestSetFromDouble(randomDouble);
+ }
+ }
+
+ @Test
+ public void testSetFromDoubleSpecial() {
+
+ for (String specialString : specialDecimalStrings) {
+ double specialDouble = Double.valueOf(specialString);
+ doTestSetFromDouble(specialDouble);
+ }
+ }
+
+ private void doTestSetFromDouble(double doubleValue) {
+
+ HiveDecimalV1 oldDec = HiveDecimalV1.create(Double.toString(doubleValue));
+ if (oldDec == null) {
+ return;
+ }
+ HiveDecimal dec = HiveDecimal.create(doubleValue);
+ if (dec == null) {
+ Assert.fail();
+ }
+ dec.validate();
+ if (!oldDec.toString().equals(dec.toString())) {
+ BigDecimal bigDecimal = new BigDecimal(dec.toString());
+ for (int i = 16; i < 18;i++) {
+ BigDecimal trial = bigDecimal.setScale(i, HiveDecimal.ROUND_HALF_UP);
+ }
+ }
+ }
+
+ //------------------------------------------------------------------------------------------------
+
+ @Test
+ public void testRandomCreateFromString() {
+ Random r = new Random(1221);
+ for (BigDecimalFlavor bigDecimalFlavor : BigDecimalFlavor.values()) {
+ doTestRandomCreateFromString(r, standardAlphabet, bigDecimalFlavor);
+ }
+ for (BigDecimalFlavor bigDecimalFlavor : BigDecimalFlavor.values()) {
+ for (String sparseAlphabet : sparseAlphabets) {
+ doTestRandomCreateFromString(r, sparseAlphabet, bigDecimalFlavor);
+ }
+ }
+ }
+
+ private void doTestRandomCreateFromString(Random r, String digitAlphabet, BigDecimalFlavor bigDecimalFlavor) {
+
+ for (int i = 0; i < POUND_FACTOR; i++) {
+ BigDecimal bigDecimal = randHiveBigDecimal(r, digitAlphabet, bigDecimalFlavor);
+
+ doTestCreateFromString(bigDecimal);
+ }
+ }
+
+ @Test
+ public void testCreateFromStringSpecial() {
+ for (BigDecimal bigDecimal : specialBigDecimals) {
+ doTestCreateFromString(bigDecimal);
+ }
+ }
+
+ private void doTestCreateFromString(BigDecimal bigDecimal) {
+
+ String decString = bigDecimal.toPlainString();
+
+ HiveDecimalV1 oldDec = HiveDecimalV1.create(decString);
+ if (oldDec != null && isTenPowerBug(oldDec.toString())) {
+ return;
+ }
+ HiveDecimal dec = HiveDecimal.create(decString);
+ if (oldDec == null) {
+ assertTrue(dec == null);
+ return;
+ }
+ assertTrue(dec != null);
+ dec.validate();
+
+ Assert.assertEquals(oldDec.toString(), dec.toString());
+ }
+
+ //------------------------------------------------------------------------------------------------
+
+ @Test
+ public void testRandomCreateFromStringPadded() {
+ Random r = new Random(9774);
+ for (BigDecimalFlavor bigDecimalFlavor : BigDecimalFlavor.values()) {
+ doTestRandomCreateFromStringPadded(r, standardAlphabet, bigDecimalFlavor);
+ }
+ for (BigDecimalFlavor bigDecimalFlavor : BigDecimalFlavor.values()) {
+ for (String sparseAlphabet : sparseAlphabets) {
+ doTestRandomCreateFromStringPadded(r, sparseAlphabet, bigDecimalFlavor);
+ }
+ }
+ }
+
+ private void doTestRandomCreateFromStringPadded(Random r, String digitAlphabet, BigDecimalFlavor bigDecimalFlavor) {
+
+ for (int i = 0; i < POUND_FACTOR; i++) {
+ BigDecimal bigDecimal = randHiveBigDecimal(r, digitAlphabet, bigDecimalFlavor);
+
+ doTestCreateFromStringPadded(bigDecimal);
+ }
+ }
+
+ @Test
+ public void testCreateFromStringPaddedSpecial() {
+ for (BigDecimal bigDecimal : specialBigDecimals) {
+ doTestCreateFromStringPadded(bigDecimal);
+ }
+ }
+
+ private void doTestCreateFromStringPadded(BigDecimal bigDecimal) {
+
+ String decString = bigDecimal.toPlainString();
+ String decString1 = " " + decString;
+ String decString2 = decString + " ";
+ String decString3 = " " + decString + " ";
+ String decString4 = " " + decString;
+ String decString5 = decString + " ";
+ String decString6 = " " + decString + " ";
+
+ HiveDecimalV1 oldDec;
+ HiveDecimal dec;
+
+ oldDec = HiveDecimalV1.create(decString);
+ if (oldDec != null && isTenPowerBug(oldDec.toString())) {
+ return;
+ }
+
+ dec = HiveDecimal.create(decString1, true);
+ if (oldDec == null) {
+ assertTrue(dec == null);
+ } else {
+ assertTrue(dec != null);
+ dec.validate();
+
+ Assert.assertEquals(oldDec.toString(), dec.toString());
+ }
+
+ dec = HiveDecimal.create(decString2, true);
+ if (oldDec == null) {
+ assertTrue(dec == null);
+ } else {
+ assertTrue(dec != null);
+ dec.validate();
+
+ Assert.assertEquals(oldDec.toString(), dec.toString());
+ }
+
+ dec = HiveDecimal.create(decString3, true);
+ if (oldDec == null) {
+ assertTrue(dec == null);
+ } else {
+ assertTrue(dec != null);
+ dec.validate();
+
+ Assert.assertEquals(oldDec.toString(), dec.toString());
+ }
+
+ dec = HiveDecimal.create(decString4, true);
+ if (oldDec == null) {
+ assertTrue(dec == null);
+ } else {
+ assertTrue(dec != null);
+ dec.validate();
+
+ Assert.assertEquals(oldDec.toString(), dec.toString());
+ }
+
+ dec = HiveDecimal.create(decString5, true);
+ if (oldDec == null) {
+ assertTrue(dec == null);
+ } else {
+ assertTrue(dec != null);
+ dec.validate();
+
+ Assert.assertEquals(oldDec.toString(), dec.toString());
+ }
+
+ dec = HiveDecimal.create(decString6, true);
+ if (oldDec == null) {
+ assertTrue(dec == null);
+ } else {
+ assertTrue(dec != null);
+ dec.validate();
+
+ Assert.assertEquals(oldDec.toString(), dec.toString());
+ }
+ }
+
+ //------------------------------------------------------------------------------------------------
+
+ @Test
+ public void testRandomCreateFromStringExponent() {
+ Random r = new Random(297111);
+ for (BigDecimalFlavor bigDecimalFlavor : BigDecimalFlavor.values()) {
+ doTestRandomCreateFromStringPadded(r, standardAlphabet, bigDecimalFlavor);
+ }
+ for (BigDecimalFlavor bigDecimalFlavor : BigDecimalFlavor.values()) {
+ for (String sparseAlphabet : sparseAlphabets) {
+ doTestRandomCreateFromStringPadded(r, sparseAlphabet, bigDecimalFlavor);
+ }
+ }
+ }
+
+ private void doTestRandomCreateFromStringExponent(Random r, String digitAlphabet, BigDecimalFlavor bigDecimalFlavor) {
+
+ for (int i = 0; i < POUND_FACTOR; i++) {
+ BigDecimal bigDecimal = randHiveBigDecimal(r, digitAlphabet, bigDecimalFlavor);
+
+ doTestCreateFromStringExponent(bigDecimal);
+ }
+ }
+
+ @Test
+ public void testCreateFromStringExponentSpecial() {
+ for (BigDecimal bigDecimal : specialBigDecimals) {
+ doTestCreateFromStringExponent(bigDecimal);
+ }
+ }
+
+ private void doTestCreateFromStringExponent(BigDecimal bigDecimal) {
+
+ // Use toString which will have exponents instead of toPlainString.
+ String decString = bigDecimal.toString();
+
+ HiveDecimalV1 oldDec = HiveDecimalV1.create(decString);
+ HiveDecimal dec = HiveDecimal.create(decString);
+ if (oldDec == null) {
+ assertTrue(dec == null);
+ return;
+ }
+ assertTrue(dec != null);
+ dec.validate();
+
+ Assert.assertEquals(oldDec.toString(), dec.toString());
+ }
+
+ //------------------------------------------------------------------------------------------------
+
+ @Test
+ public void testRandomLongValue() {
+ Random r = new Random(73293);
+ for (BigDecimalFlavor bigDecimalFlavor : BigDecimalFlavor.values()) {
+ doTestRandomLongValue(r, standardAlphabet, bigDecimalFlavor);
+ }
+ for (BigDecimalFlavor bigDecimalFlavor : BigDecimalFlavor.values()) {
+ for (String sparseAlphabet : sparseAlphabets) {
+ doTestRandomLongValue(r, sparseAlphabet, bigDecimalFlavor);
+ }
+ }
+ }
+
+ private void doTestRandomLongValue(Random r, String digitAlphabet, BigDecimalFlavor bigDecimalFlavor) {
+
+ for (int i = 0; i < POUND_FACTOR; i++) {
+ BigDecimal bigDecimal = randHiveBigDecimal(r, digitAlphabet, bigDecimalFlavor);
+
+ doTestLongValue(bigDecimal);
+ }
+ }
+
+ @Test
+ public void testLongValueSpecial() {
+ for (BigDecimal bigDecimal : specialBigDecimals) {
+ doTestLongValue(bigDecimal);
+ }
+ }
+
+ private void doTestLongValue(BigDecimal bigDecimal) {
+
+ HiveDecimalV1 oldDec = HiveDecimalV1.create(bigDecimal);
+ if (oldDec != null && isTenPowerBug(oldDec.toString())) {
+ return;
+ }
+ HiveDecimal dec = HiveDecimal.create(bigDecimal);
+ if (oldDec == null) {
+ assertTrue(dec == null);
+ return;
+ }
+ assertTrue(dec != null);
+ dec.validate();
+
+ BigDecimal bigDecimalOldDec = oldDec.bigDecimalValue();
+ BigDecimal bigDecimalDec = dec.bigDecimalValue();
+ Assert.assertEquals(bigDecimalOldDec, bigDecimalDec);
+
+ BigDecimal bigDecimalFloor = bigDecimalDec.setScale(0, BigDecimal.ROUND_DOWN);
+ long longValueBigDecimalFloor = bigDecimalFloor.longValue();
+ boolean isLongExpected =
+ bigDecimalFloor.equals(bigDecimalDec.valueOf(longValueBigDecimalFloor));
+
+ boolean decIsLong = dec.isLong();
+ long oldDecLong = oldDec.longValue();
+ long decLong = dec.longValue();
+ if (isLongExpected != decIsLong) {
+ Assert.fail();
+ }
+
+ if (decIsLong) {
+ if (oldDecLong != decLong) {
+ Assert.fail();
+ }
+ }
+ }
+
+ //------------------------------------------------------------------------------------------------
+
+ @Test
+ public void testRandomIntValue() {
+ Random r = new Random(98333);
+ for (BigDecimalFlavor bigDecimalFlavor : BigDecimalFlavor.values()) {
+ doTestRandomIntValue(r, standardAlphabet, bigDecimalFlavor);
+ }
+ for (BigDecimalFlavor bigDecimalFlavor : BigDecimalFlavor.values()) {
+ for (String sparseAlphabet : sparseAlphabets) {
+ doTestRandomIntValue(r, sparseAlphabet, bigDecimalFlavor);
+ }
+ }
+ }
+
+ private void doTestRandomIntValue(Random r, String digitAlphabet, BigDecimalFlavor bigDecimalFlavor) {
+
+ for (int i = 0; i < POUND_FACTOR; i++) {
+ BigDecimal bigDecimal = randHiveBigDecimal(r, digitAlphabet, bigDecimalFlavor);
+
+ doTestIntValue(bigDecimal);
+ }
+ }
+
+ @Test
+ public void testIntValueSpecial() {
+ for (BigDecimal bigDecimal : specialBigDecimals) {
+ doTestIntValue(bigDecimal);
+ }
+ }
+
+ private void doTestIntValue(BigDecimal bigDecimal) {
+
+ HiveDecimalV1 oldDec = HiveDecimalV1.create(bigDecimal);
+ if (oldDec != null && isTenPowerBug(oldDec.toString())) {
+ return;
+ }
+ HiveDecimal dec = HiveDecimal.create(bigDecimal);
+ if (oldDec == null) {
+ assertTrue(dec == null);
+ return;
+ }
+ assertTrue(dec != null);
+ dec.validate();
+
+ BigDecimal bigDecimalOldDec = oldDec.bigDecimalValue();
+ BigDecimal bigDecimalDec = dec.bigDecimalValue();
+ Assert.assertEquals(bigDecimalOldDec, bigDecimalDec);
+
+ BigDecimal bigDecimalFloor = bigDecimalDec.setScale(0, BigDecimal.ROUND_DOWN);
+ int intValueBigDecimalFloor = bigDecimalFloor.intValue();
+ boolean isIntExpected =
+ bigDecimalFloor.equals(bigDecimalDec.valueOf(intValueBigDecimalFloor));
+
+ boolean decIsInt = dec.isInt();
+ int oldDecInt = oldDec.intValue();
+ int decInt = dec.intValue();
+ if (isIntExpected != decIsInt) {
+ Assert.fail();
+ }
+
+ if (decIsInt) {
+ if (oldDecInt != decInt) {
+ Assert.fail();
+ }
+ }
+ }
+
+ //------------------------------------------------------------------------------------------------
+
+ @Test
+ public void testRandomShortValue() {
+ Random r = new Random(15);
+ for (BigDecimalFlavor bigDecimalFlavor : BigDecimalFlavor.values()) {
+ doTestRandomShortValue(r, standardAlphabet, bigDecimalFlavor);
+ }
+ for (BigDecimalFlavor bigDecimalFlavor : BigDecimalFlavor.values()) {
+ for (String sparseAlphabet : sparseAlphabets) {
+ doTestRandomShortValue(r, sparseAlphabet, bigDecimalFlavor);
+ }
+ }
+ }
+
+ private void doTestRandomShortValue(Random r, String digitAlphabet, BigDecimalFlavor bigDecimalFlavor) {
+ for (int i = 0; i < POUND_FACTOR; i++) {
+ BigDecimal bigDecimal = randHiveBigDecimal(r, digitAlphabet, bigDecimalFlavor);
+
+ doTestShortValue(bigDecimal);
+ }
+ }
+
+ @Test
+ public void testShortValueSpecial() {
+ for (BigDecimal bigDecimal : specialBigDecimals) {
+ doTestShortValue(bigDecimal);
+ }
+ }
+
+ private void doTestShortValue(BigDecimal bigDecimal) {
+
+ HiveDecimalV1 oldDec = HiveDecimalV1.create(bigDecimal);
+ if (oldDec != null && isTenPowerBug(oldDec.toString())) {
+ return;
+ }
+ HiveDecimal dec = HiveDecimal.create(bigDecimal);
+ if (oldDec == null) {
+ assertTrue(dec == null);
+ return;
+ }
+ assertTrue(dec != null);
+ dec.validate();
+
+ BigDecimal bigDecimalOldDec = oldDec.bigDecimalValue();
+ BigDecimal bigDecimalDec = dec.bigDecimalValue();
+ Assert.assertEquals(bigDecimalOldDec, bigDecimalDec);
+
+ BigDecimal bigDecimalFloor = bigDecimalDec.setScale(0, BigDecimal.ROUND_DOWN);
+ short shortValueBigDecimalFloor = bigDecimalFloor.shortValue();
+ boolean isShortExpected =
+ bigDecimalFloor.equals(bigDecimalDec.valueOf(shortValueBigDecimalFloor));
+
+ boolean decIsShort = dec.isShort();
+ short oldDecShort = oldDec.shortValue();
+ short decShort = dec.shortValue();
+ if (isShortExpected != decIsShort) {
+ Assert.fail();
+ }
+
+ if (decIsShort) {
+ if (oldDecShort != decShort) {
+ Assert.fail();
+ }
+ }
+ }
+
+ //------------------------------------------------------------------------------------------------
+
+ @Test
+ public void testRandomByteValue() {
+ Random r = new Random(9292);
+ for (BigDecimalFlavor bigDecimalFlavor : BigDecimalFlavor.values()) {
+ doTestRandomByteValue(r, standardAlphabet, bigDecimalFlavor);
+ }
+ for (BigDecimalFlavor bigDecimalFlavor : BigDecimalFlavor.values()) {
+ for (String sparseAlphabet : sparseAlphabets) {
+ doTestRandomByteValue(r, sparseAlphabet, bigDecimalFlavor);
+ }
+ }
+ }
+
+ private void doTestRandomByteValue(Random r, String digitAlphabet, BigDecimalFlavor bigDecimalFlavor) {
+
+ for (int i = 0; i < POUND_FACTOR; i++) {
+ BigDecimal bigDecimal = randHiveBigDecimal(r, digitAlphabet, bigDecimalFlavor);
+
+ doTestByteValue(bigDecimal);
+ }
+ }
+
+ @Test
+ public void testByteValueSpecial() {
+ for (BigDecimal bigDecimal : specialBigDecimals) {
+ doTestByteValue(bigDecimal);
+ }
+ }
+
+ private void doTestByteValue(BigDecimal bigDecimal) {
+
+ HiveDecimalV1 oldDec = HiveDecimalV1.create(bigDecimal);
+ if (oldDec != null && isTenPowerBug(oldDec.toString())) {
+ return;
+ }
+ HiveDecimal dec = HiveDecimal.create(bigDecimal);
+ if (oldDec == null) {
+ assertTrue(dec == null);
+ return;
+ }
+ assertTrue(dec != null);
+ dec.validate();
+
+ BigDecimal bigDecimalOldDec = oldDec.bigDecimalValue();
+ BigDecimal bigDecimalDec = dec.bigDecimalValue();
+ Assert.assertEquals(bigDecimalOldDec, bigDecimalDec);
+
+ BigDecimal bigDecimalFloor = bigDecimalDec.setScale(0, BigDecimal.ROUND_DOWN);
+ byte byteValueBigDecimalFloor = bigDecimalFloor.byteValue();
+ boolean isByteExpected =
+ bigDecimalFloor.equals(bigDecimalDec.valueOf(byteValueBigDecimalFloor));
+
+ boolean decIsByte = dec.isByte();
+ byte oldDecByte = oldDec.byteValue();
+ byte decByte = dec.byteValue();
+ if (isByteExpected != decIsByte) {
+ Assert.fail();
+ }
+
+ if (decIsByte) {
+ if (oldDecByte != decByte) {
+ Assert.fail();
+ }
+ }
+ }
+
+ //------------------------------------------------------------------------------------------------
+
+ @Test
+ public void testRandomTimestamp() {
+ Random r = new Random(5476);
+ for (BigDecimalFlavor bigDecimalFlavor : BigDecimalFlavor.values()) {
+ doTestRandomTimestamp(r, standardAlphabet, bigDecimalFlavor);
+ }
+ for (BigDecimalFlavor bigDecimalFlavor : BigDecimalFlavor.values()) {
+ for (String sparseAlphabet : sparseAlphabets) {
+ doTestRandomTimestamp(r, sparseAlphabet, bigDecimalFlavor);
+ }
+ }
+ }
+
+ private void doTestRandomTimestamp(Random r, String digitAlphabet, BigDecimalFlavor bigDecimalFlavor) {
+ for (int i = 0; i < POUND_FACTOR; i++) {
+ BigDecimal bigDecimal = randHiveBigDecimal(r, digitAlphabet, bigDecimalFlavor);
+
+ doTestTimestamp(bigDecimal);
+ }
+ }
+
+ @Test
+ public void testTimestampSpecial() {
+ for (BigDecimal bigDecimal : specialBigDecimals) {
+ doTestTimestamp(bigDecimal);
+ }
+ }
+
+ private void doTestTimestamp(BigDecimal bigDecimal) {
+
+ HiveDecimalV1 oldDec = HiveDecimalV1.create(bigDecimal);
+ if (oldDec != null && isTenPowerBug(oldDec.toString())) {
+ return;
+ }
+ HiveDecimal dec = HiveDecimal.create(bigDecimal);
+ if (oldDec == null) {
+ assertTrue(dec == null);
+ return;
+ }
+ assertTrue(dec != null);
+
<TRUNCATED>